LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: Evil-Devil on September 05, 2005, 16:18:37

Title: One way of using DDS texture files
Post by: Evil-Devil on September 05, 2005, 16:18:37
Hi folks, as i refactor my DDS Textureloader classes, I thought about sharing this stuff. As I got the first steps from the old wiki DDS Tutorial which was a little bit crappy to handle. If wished, i will add this to the wiki. As soon the code is finished.

For the moment there is no mipmap loading, but that will included soon.
DXT1, DXT1 (with alpha), DXT3 and DXT5 are supported. I have not tested with the RGB format, but i think about implementing full support for   that too.
Feel free to utilize the classes to your need and please give some comments :)

Benny

DDSLoader.java
/* =============================================================================
* DDSLoader.java Bubble_Engine
* com.evildevil.engines.bubble.texture
* Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt
* All rights reserved
* -----------------------------------------------------------------------------
* powered by LWJGL - Copyright (c) LWJGL Team (http://www.lwjgl.org)
* powered by JAVA - Copyright (c) Sun Microsystems (http://www.sun.com)
* -------------------------------------------------------------------------- */
package com.evildevil.engines.bubble.texture;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.channels.FileChannel;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;

import static org.lwjgl.opengl.EXTTextureCompressionS3TC.*;
import static org.lwjgl.opengl.GL11.GL_LINEAR;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
import static org.lwjgl.opengl.GL11.glTexParameteri;

/**
* <p>DDSLoader.java Bubble Engine</p>
* <p><strong>Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt<br />
* All rights reserved</strong><br />
* Website: <a href="http://www.evil-devil.com" target="_blank">http://www.evil-devil.com</a></p><hr />
* @author Benjamin "Evil-Devil" Behrendt
* @version 1.0, 02.09.2005
* <p>This class provides an example view about how to load a texture that uses<br>
* the DDS (Direct Draw Surface) file format.<br />
* This is not a common engine Bubble Engine class nor should it be used as it, there are
* other classes for loading dds and other texture format files :D
*/
public final class DDSLoader implements DDSurface {
   
   private final String DDS_IDENTIFIER = "DDS ";
   private final int DDS_HEADER_SIZE = 128;        // size of the dds header
   private final int DDS_DESC2_RESERVED_1 = 44;    // bytesize of DWORD[11]
   private final int DDS_DESC2_RESERVED_2 = 4;     // bytesize of DWORD
   private final int DDS_CAPS2_RESERVED = 8;       // bytesize of DWORD[2]
   private final int DEFAULT_DXT_BLOCKSIZE = 16;
   private final int DXT1_BLOCKSIZE = 8;
   
   private DDSurfaceDesc2 ddsDesc2 = null;
   private ByteBuffer ddsHeader = null;
   private FileChannel ddsFileChannel = null;
   
   public DDSLoader() {
   }
   
   public int loadDDSFile(String fileName) {
       // our DDS file
       File ddsFile = new File(fileName);
       
       try {
           FileInputStream fis = new FileInputStream(ddsFile);
           // assign the filechannel for reading data from it
           ddsFileChannel = fis.getChannel();
           // check for null
           if (ddsFileChannel == null)
               throw new NullPointerException("ddsFileChannel couldn't be null!");
       } catch (FileNotFoundException fnfe) {
           fnfe.printStackTrace();
       }
       
       // create a new DDSurfaceDesc2 object to hold all dds file information
       ddsDesc2 = new DDSurfaceDesc2();
       // allocate enough memory for storing the whole header
       ddsHeader = BufferUtils.createByteBuffer(DDS_HEADER_SIZE);
       readFileHeader();
       int glName = readFileData();
       return glName;
   }
   
   private void readFileHeader() {
       
       try {
           // read the header
           ddsFileChannel.read(ddsHeader);
           ddsHeader.rewind();
           
           // read and feed the DDSurfaceDesc2            
           ddsDesc2.setIdentifier(ddsHeader.getInt());
           ddsDesc2.setSize(ddsHeader.getInt());
           ddsDesc2.setFlags(ddsHeader.getInt());
           ddsDesc2.setHeight(ddsHeader.getInt());
           ddsDesc2.setWidth(ddsHeader.getInt());
           ddsDesc2.setPitchOrLinearSize(ddsHeader.getInt());
           ddsDesc2.setDepth(ddsHeader.getInt());
           ddsDesc2.setMipMapCount(ddsHeader.getInt());
           // skip, cause next is unused
           ddsHeader.position(ddsHeader.position()+DDS_DESC2_RESERVED_1);
           
           // DDPixelFormat of DDSurfaceDesc2            
           DDPixelFormat pixelFormat = ddsDesc2.getDDPixelformat();
           pixelFormat.setSize(ddsHeader.getInt());
           pixelFormat.setFlags(ddsHeader.getInt());
           pixelFormat.setFourCC(ddsHeader.getInt());
           pixelFormat.setRGBBitCount(ddsHeader.getInt());
           pixelFormat.setRBitMask(ddsHeader.getInt());
           pixelFormat.setGBitMask(ddsHeader.getInt());
           pixelFormat.setBBitMask(ddsHeader.getInt());
           pixelFormat.setRGBAlphaBitMask(ddsHeader.getInt());
           
           // DDSCaps2 of DDSurfaceDesc2
           DDSCaps2 caps2 = ddsDesc2.getDDSCaps2();
           caps2.setCaps1(ddsHeader.getInt());
           caps2.setCaps2(ddsHeader.getInt());
                   
           // skip, cause next is unused
           ddsHeader.position(ddsHeader.position()+DDS_CAPS2_RESERVED);
           
           // we don't wanna read the last 4 bytes, they are not used anyway,
           // but we skip them. Funny, ain't?
           ddsHeader.position(ddsHeader.position()+DDS_DESC2_RESERVED_2);            
           // the last two instuctions might be banned, but thats your decission
       
       } catch (BufferUnderflowException bue) {
           bue.printStackTrace();
       } catch (TextureFormatException tfe) {
           tfe.printStackTrace();
       } catch (IOException ioe) {
           ioe.printStackTrace();
       } finally {
           ddsHeader = null;   // free the memory
       }
   }
   
   private int readFileData() {
       final DDPixelFormat ddpf = ddsDesc2.getDDPixelformat();
       int imageSize = 0;
       int dxtFormat = 0;
       
       /* calculate the image size depending on the used blocksize
          and set the used DXT format */
       if (ddpf.isCompressed && ddpf.getFourCCString().equalsIgnoreCase("DXT1")) {
           imageSize = calculateSize(DXT1_BLOCKSIZE);
           // at the moment we treat any DXT1 image as RGBA,
           // maybe this can be switched dynamically in future...
           dxtFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
       } else {
           imageSize = calculateSize(DEFAULT_DXT_BLOCKSIZE);
           if (ddpf.getFourCCString().equalsIgnoreCase("DXT3"))
               dxtFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
           else if(ddpf.getFourCCString().equals("DXT5"))
               dxtFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
       }
       
       // read the dds file data itself
       ByteBuffer imageData = BufferUtils.createByteBuffer(ddsDesc2.pitchOrLinearSize);
       
       try {
           ddsFileChannel.read(imageData);
           imageData.rewind();            
       } catch (IOException ioe) {
           ioe.printStackTrace();
       }
       
       // create the GL Name
       IntBuffer glName = BufferUtils.createIntBuffer(1);        
       
       // create the texture
       GL11.glGenTextures(glName);
       GL11.glBindTexture(GL11.GL_TEXTURE_2D,glName.get(0));
       
       /* Implement the filtering stuff anywhere you want, this is only here to
          have at least one filter applied on the texture */
       // Linear Filtering
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       
       GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_S,GL11.GL_REPEAT);
       GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_T,GL11.GL_REPEAT);
       GL13.glCompressedTexImage2D(GL11.GL_TEXTURE_2D,0,dxtFormat,ddsDesc2.width,ddsDesc2.height,0,ddsDesc2.pitchOrLinearSize,imageData);
       
       return glName.get(0);
   }
   
   private int calculateSize(int blockSize) {
       double size = Math.ceil(ddsDesc2.width/4) * Math.ceil(ddsDesc2.height/4) * blockSize;
       return (int)size;
   }
   
   public void debugInfo() {        
       DDPixelFormat pixelFormat = ddsDesc2.getDDPixelformat();
       DDSCaps2 caps2 = ddsDesc2.getDDSCaps2();
       
       System.out.println("\nDDSURFACEDESC2:");
       System.out.println("----------------------------------------");
       System.out.println("SIZE: "+ddsDesc2.size);
       System.out.println("FLAGS: "+ddsDesc2.flags);
       System.out.println("HEIGHT: "+ddsDesc2.height);
       System.out.println("WIDTH: "+ddsDesc2.width);
       System.out.println("PITCH_OR_LINEAR_SIZE: "+ddsDesc2.pitchOrLinearSize);
       System.out.println("DEPTH: "+ddsDesc2.depth);
       System.out.println("MIP_MAP_COUNT: "+ddsDesc2.mipMapCount);
       
       System.out.println("\nDDPIXELFORMAT of DDSURFACEDESC2:");
       System.out.println("----------------------------------------");
       System.out.println("SIZE :"+pixelFormat.size);
       System.out.println("FLAGS: "+pixelFormat.flags);
       System.out.println("FOUR_CC: "+pixelFormat.getFourCCString());
       System.out.println("RGB_BIT_COUNT: "+pixelFormat.rgbBitCount);
       System.out.println("R_BIT_MASK: "+pixelFormat.rBitMask);
       System.out.println("G_BIT_MASK: "+pixelFormat.gBitMask);
       System.out.println("B_BIT_MASK: "+pixelFormat.bBitMask);
       System.out.println("RGB_ALPHA_BIT_MASK: "+pixelFormat.rgbAlphaBitMask);    
       
       System.out.println("\nDDSCAPS of DDSURFACEDESC2");
       System.out.println("----------------------------------------");
       System.out.println("CAPS1: "+caps2.caps1);
       System.out.println("CAPS2: "+caps2.caps2);    
   }
}

DDSurface.java
/* =============================================================================
* DDSurface.java Bubble_Engine
* com.evildevil.engines.bubble.texture
* Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt
* All rights reserved
* -----------------------------------------------------------------------------
* powered by LWJGL - Copyright (c) LWJGL Team (http://www.lwjgl.org)
* powered by JAVA - Copyright (c) Sun Microsystems (http://www.sun.com)
* -------------------------------------------------------------------------- */
package com.evildevil.engines.bubble.texture;

/**
* <p>DDSurface.java Bubble Engine</p>
* <p><strong>Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt<br />
* All rights reserved</strong><br />
* Website: <a href="http://www.evil-devil.com" target="_blank">http://www.evil-devil.com</a></p><hr />
* @author Benjamin "Evil-Devil" Behrendt
* @version 1.0, 02.09.2005
*/
interface DDSurface {
   
   // dwFags - DDSurfaceDesc2
   int DDSD_CAPS           = 0x00000001;
   int DDSD_HEIGHT         = 0x00000002;
   int DDSD_WIDTH          = 0x00000004;
   int DDSD_PITCH          = 0x00000008;
   int DDSD_PIXELFORMAT    = 0x00001000;
   int DDSD_MIPMAPCOUNT    = 0x00020000;
   int DDSD_LINEARSIZE      = 0x00080000;
   int DDSD_DEPTH          = 0x00800000;
   
   // ddpfPixeFormat - DDSurfaceDesc2
   int DDPF_APHAPIXES  = 0x00000001;
   int DDPF_FOURCC     = 0x00000004;
   int DDPF_RGB        = 0x00000040;
   
   // dwCaps1  - DDSCaps2
   int DDSCAPS_COMPLEX    = 0x00000008;
   int DDSCAPS_TEXTURE    = 0x00001000;
   int DDSCAPS_MIPMAP     = 0x00400000;
   
   // dwCaps2 - DDSCaps2
   int DDSCAPS2_CUBEMAP            = 0x00000200;
   int DDSCAPS2_CUBEMAP_POSITVEX   = 0x00000400;
   int DDSCAPS2_CUBEMAP_NEGATIVEX  = 0x00000800;
   int DDSCAPS2_CUBEMAP_POSITIVEY  = 0x00001000;
   int DDSCAPS2_CUBEMAP_NEGATIVEY  = 0x00002000;
   int DDSCAPS2_CUBEMAP_POSITIVEZ  = 0x00004000;
   int DDSCAPS2_CUBEMAP_NEGATIVEZ  = 0x00008000;
   int DDSCAPS2_VOLUME              = 0x00200000;

}

DDSurfaceDesc2.java
/* =============================================================================
* DDSurfaceDesc2.java Bubbe_Engine
* com.evildevil.engines.bubble.texture
* Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt
* All rights reserved
* -----------------------------------------------------------------------------
* powered by LWJGL - Copyright (c) LWJGL Team (http://www.lwjgl.org)
* powered by JAVA - Copyright (c) Sun Microsystems (http://www.sun.com)
* -------------------------------------------------------------------------- */
package com.evildevil.engines.bubble.texture;

/**
* <p>DDSurfaceDesc2.java Bubble Engine</p>
* <p><strong>Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt<br />
* All rights reserved</strong><br />
* Website: <a href="http://www.evil-devil.com" target="_bank">http://www.evil-devil.com</a></p><hr />
* @author Benjamin "Evil-Devil" Behrendt
* @version 1.0, 02.09.2005
*/
final class DDSurfaceDesc2 implements DDSurface {
   
   private final String DDS_IDENTIFIER = "DDS ";
   protected int identifier = 0;
   private String identifierString = "";
   protected int size = 0;                     // size of the structure, must be 124
   protected int flags = 0;
   protected int height = 0;
   protected int width = 0;
   protected int pitchOrLinearSize = 0;
   protected int depth = 0;
   protected int mipMapCount = 0;
   protected int reserved = 0;                 // unused by documentation
   private DDPixelFormat pixelFormat = null;   // the surfaces DDPixelFormat
   private DDSCaps2 caps2 = null;              // the surfaces DDSCaps2
   protected int reserved2 = 0;                // unused by documentation
       
   public DDSurfaceDesc2() {
       pixelFormat = new DDPixelFormat();
       caps2 = new DDSCaps2();
   }
   
   public void setIdentifier(int identifier) throws TextureFormatException {
       this.identifier = identifier;
       createIdentifierString();
   }
   
   private void createIdentifierString() throws TextureFormatException {
       byte[] identifierString = new byte[4];
       identifierString[0] = (byte)this.identifier;
       identifierString[1] = (byte)(this.identifier >> 8);
       identifierString[2] = (byte)(this.identifier >> 16);
       identifierString[3] = (byte)(this.identifier >> 24);
       
       this.identifierString = new String(identifierString);
       // validate
       if (!this.identifierString.equalsIgnoreCase(this.DDS_IDENTIFIER)) {
           throw new TextureFormatException("The DDS Identifier is wrong. Have to be \"DDS \"!");
       }
   }
   
   public void setSize(int size) throws TextureFormatException{
       if (size != 124)    // TODO: include your own Exception handling here!
           throw new TextureFormatException("Wrong DDSurfaceDesc2 size. DDSurfaceDesc2 size must be 124!");        
       this.size = size;
   }
   
   public void setFlags(int flags) throws TextureFormatException {
       this.flags = flags;
       // check for DDSD_CAPS, DDSD_PIXELFORMAT, DDSD_WIDTH, DDSD_HEIGHT
       if ((flags & DDSD_CAPS) != DDSD_CAPS || (flags & DDSD_PIXELFORMAT) != DDSD_PIXELFORMAT
               || (flags & DDSD_WIDTH) != DDSD_WIDTH || (flags & DDSD_HEIGHT) != DDSD_HEIGHT)
           throw new TextureFormatException("One or more required flag bits are set wrong\n"+
                   "flags have to include \"DDSD_CAPS, DDSD_PIXELFORMAT, DDSD_WIDTH, DDSD_HEIGHT\"");
   }
   
   public void setHeight(int height) {
       this.height = height;
   }
   
   public void setWidth(int width) {
       this.width = width;
   }
   
   public void setPitchOrLinearSize(int pitchOrLinearSize) {
       this.pitchOrLinearSize = pitchOrLinearSize;
   }
   
   public void setDepth(int depth) {
       this.depth = depth;
   }
   
   public void setMipMapCount(int mipMapCount) {
       this.mipMapCount = mipMapCount;
   }
   
   public void setDDPixelFormat(DDPixelFormat pixelFormat) throws NullPointerException {
       if (pixelFormat == null)
           throw new NullPointerException("DDPixelFormat can't be null. DDSurfaceDesc2 needs a valid DDPixelFormat.");
       this.pixelFormat = pixelFormat;
   }
   
   public DDPixelFormat getDDPixelformat() {
       return pixelFormat;
   }
   
   public void setDDSCaps2(DDSCaps2 caps2) throws NullPointerException {
       if (caps2 == null)
           throw new NullPointerException("DDSCaps can't be null. DDSurfaceDesc2 needs a valid DDSCaps2.");
       this.caps2 = caps2;
   }
   
   public DDSCaps2 getDDSCaps2() {
       return caps2;
   }
}

DDPixelFormat.java
/* =============================================================================
* DDPixelFormat.java Bubble_Engine
* com.evildevil.engines.bubble.texture
* Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt
* All rights reserved
* -----------------------------------------------------------------------------
* powered by LWJGL - Copyright (c) LWJGL Team (http://www.lwjgl.org)
* powered by JAVA - Copyright (c) Sun Microsystems (http://www.sun.com)
* -------------------------------------------------------------------------- */
package com.evildevil.engines.bubble.texture;

/**
* <p>DDPixelFormat.java Bubble Engine</p>
* <p><strong>Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt<br />
* All rights reserved</strong><br />
* Website: <a href="http://www.evil-devil.com" target="_blank">http://www.evil-devil.com</a></p><hr />
* @author Benjamin "Evil-Devil" Behrendt
* @version 1.0, 02.09.2005
*/
final class DDPixelFormat implements DDSurface {
   
   protected int size = 0;             // this must be set to 32!
   protected int flags = 0;
   protected int fourCC = 0;
   private String fourCCString = "";
   protected int rgbBitCount = 0;
   protected int rBitMask = 0;
   protected int gBitMask = 0;
   protected int bBitMask = 0;
   protected int rgbAlphaBitMask = 0;
   
   protected boolean isCompressed = true;
   
   public DDPixelFormat() {        
   }
   
   public void setSize(int size) throws TextureFormatException {
       if (size != 32)
           throw new TextureFormatException("Wrong DDPixelFormat size. DDPixelFormat size must be 32!");        
       this.size = size;
   }
       
   public void setFlags(int flags) {
       this.flags = flags;
       // check for (un)compressed
       if ((flags & DDPF_RGB) == DDPF_RGB)
           this.isCompressed = false;
       else if ((flags & DDPF_FOURCC) == DDPF_FOURCC)
           this.isCompressed = true;
   }
   
   public void setFourCC(int fourCC) {
       this.fourCC = fourCC;        
       if (this.isCompressed)
           createFourCCString();       // create the fourCCString
   }
   
   private void createFourCCString() {        
       byte[] fourCCString = new byte[DDPF_FOURCC];
       fourCCString[0] = (byte)this.fourCC;
       fourCCString[1] = (byte)(this.fourCC >> 8);
       fourCCString[2] = (byte)(this.fourCC >> 16);
       fourCCString[3] = (byte)(this.fourCC >> 24);
       // fourCCString is done :)
       this.fourCCString = new String(fourCCString);        
   }
   
   public String getFourCCString() {
       return this.fourCCString;
   }
   
   public void setRGBBitCount(int rgbBitCount) {
       this.rgbAlphaBitMask = rgbBitCount;
   }
   
   public void setRBitMask(int rBitMask) {
       this.rBitMask = rBitMask;
   }
   
   public void setGBitMask(int gBitMask) {
       this.gBitMask = gBitMask;
   }
   
   public void setBBitMask(int bBitMask) {
       this.bBitMask = bBitMask;
   }
   
   public void setRGBAlphaBitMask(int rgbAlphaBitMask) {
       this.rgbAlphaBitMask = rgbAlphaBitMask;
   }
}

DDSCaps2
/* =============================================================================
* DDSCaps2.java Bubble_Engine
* com.evildevil.engines.bubble.texture
* Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt
* All rights reserved
* -----------------------------------------------------------------------------
* powered by LWJGL - Copyright (c) LWJGL Team (http://www.lwjgl.org)
* powered by JAVA - Copyright (c) Sun Microsystems (http://www.sun.com)
* -------------------------------------------------------------------------- */
package com.evildevil.engines.bubble.texture;

/**
* <p>DDSCaps2.java Bubble Engine</p>
* <p><strong>Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt<br />
* All rights reserved</strong><br />
* Website: <a href="http://www.evil-devil.com" target="_blank">http://www.evil-devil.com</a></p><hr />
* @author Benjamin "Evil-Devil" Behrendt
* @version 1.0, 02.09.2005
*/
final class DDSCaps2 implements DDSurface {
   
   public DDSCaps2() {        
   }
   
   protected int caps1 = 0;
   protected int caps2 = 0;
   protected int reserved = 0;       // unused by documentation
   
   protected boolean isVolumeTexture = false;
   
   public void setCaps1(int caps1) throws TextureFormatException {        
       this.caps1 = caps1;
       if ((caps1 & DDSCAPS_TEXTURE) != DDSCAPS_TEXTURE)   // check for DDSCAPS_TEXTURE
           throw new TextureFormatException("DDS file does not contain DDSCAPS_TEXTURE, but it must!");
   }  
   
   public void setCaps2(int caps2) {
       this.caps2 = caps2;
       // check for VolumeTexture
       if ((caps2 & DDSCAPS2_VOLUME) == DDSCAPS2_VOLUME)
           this.isVolumeTexture = true;
   }
}

TextureFormatException.java
/* =============================================================================
* DDPixelFormat.java Bubble_Engine
* com.evildevil.engines.bubble.texture
* Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt
* All rights reserved
* -----------------------------------------------------------------------------
* powered by LWJGL - Copyright (c) LWJGL Team (http://www.lwjgl.org)
* powered by JAVA - Copyright (c) Sun Microsystems (http://www.sun.com)
* -------------------------------------------------------------------------- */
package com.evildevil.engines.bubble.texture;

/**
* <p>DDPixelFormat.java Bubble Engine</p>
* <p><strong>Copyright (c) 2004 - 2005 Benjamin "Evil-Devil" Behrendt<br />
* All rights reserved</strong><br />
* Website: <a href="http://www.evil-devil.com" target="_blank">http://www.evil-devil.com</a></p><hr />
* @author Benjamin "Evil-Devil" Behrendt
* @version 1.0, 27.01.2005
*/
public class TextureFormatException extends Exception {
   
   private static final long serialVersionUID = 24L;
   
   public TextureFormatException() {
       super();
   }
   
   public TextureFormatException(String s) {
       super(s);            
   }
}
Title: hmmmmmm...
Post by: Fool Running on September 05, 2005, 19:06:35
Very impressive  :shock:
Title: One way of using DDS texture files
Post by: chaosdeathfish on September 06, 2005, 19:18:40
But DevIL can load DDS textures. Why are you using your own loader?
Title: One way of using DDS texture files
Post by: Evil-Devil on September 08, 2005, 07:04:47
Really? I haven't known.

Ok, then I have to add a DevIL implementation to my TextureLoader.
And if not using DevIL, there are no JNI calls :)
Title: One way of using DDS texture files
Post by: chaosdeathfish on September 08, 2005, 12:02:45
..although having said that, aparently there's some call you have to make before you load the texture to stop DevIL decompressing the textures itself.. I can't remember what it is though. Sorry :(