[quote="<MagicSpark.org [ BlueSky ]>,post:10,topic:27443"]
Must be very useful when you feel lonely… ;D ;D
[/quote]
This is a very useful contribution - thank you.
The DirectX stuff works only for Windows.
The nVidia stuff is only allowed to be used if you have an nVidia card (they say that in there license).
But you could take a look at o3tc: http://www.ozone3d.net
I have the code for this lying around (but not yet ported to Xith3D):
public class TextureStreamLoaderO3TC implements TextureStreamLoader {
private static final int HEADER_ID = 0x4354334F;
private static final int O3_TC_RGB_S3TC_DXT1 = 1;
private static final int O3_TC_RGBA_S3TC_DXT5 = 4;
private static final int O3_TC_ATI3DC_ATI2N = 16;
/** Creates a new instance of TextureStreamLoaderO3TC */
public TextureStreamLoaderO3TC() {
}
public Texture loadTexture(InputStream in) throws IOException {
int dataSize = readLE32(in);
int header = readLE32(in);
int headerSize = readLE32(in);
int version = readLE32(in);
if(header != HEADER_ID || headerSize != 12 || version != 1 || dataSize < 12) {
return null;
}
dataSize -= 12;
int chunkHeaderSize = readLE32(in);
int reserved1 = readLE32(in);
int chunkDataSize = readLE32(in);
int reserved2 = readLE32(in);
int format = readLE32(in);
int width = readLE32(in);
int height = readLE32(in);
int depth = readLE32(in);
int numMipMaps = readLE32(in);
byte[] textureName = new byte[128];
readFully(in, textureName, 0, 128);
int textureId = readLE32(in);
if(chunkHeaderSize != 168 || width < 1 || height < 1 ||
width > 4096 || height > 4096 || depth < 0 ||
depth > 256 || numMipMaps < 1 || numMipMaps > 12 ||
dataSize < 168) {
return null;
}
dataSize -= 168;
if(chunkDataSize < dataSize) {
return null;
}
TextureShader.TextureFormat texFormat;
TextureShader.TextureFormatHint texFormatHint;
int blockSize;
switch (format) {
case O3_TC_RGB_S3TC_DXT1:
texFormat = TextureShader.TextureFormat.DXT1;
texFormatHint = TextureShader.TextureFormatHint.DXT1;
blockSize = 8;
break;
case O3_TC_RGBA_S3TC_DXT5:
texFormat = TextureShader.TextureFormat.DXT5;
texFormatHint = TextureShader.TextureFormatHint.DXT5;
blockSize = 16;
break;
default:
return null;
}
if(depth == 0) {
Texture2D tex = new Texture2D(texFormat, width, height);
ByteBuffer[] data = new ByteBuffer[numMipMaps];
for(int i=0 ; i<numMipMaps ; ++i) {
int size = ((width+3)/4) * ((height+3)/4) * blockSize;
if(size > chunkDataSize) {
return null;
}
chunkDataSize -= size;
data[i] = BufferUtils.createByteBuffer(size);
readFully(in, data[i]);
data[i].flip();
width = Math.max(1, width >> 1);
height = Math.max(1, height >> 1);
}
if(chunkDataSize > 0) {
return null;
}
tex.setFormatHint(texFormatHint);
tex.setData(data);
return tex;
} else {
throw new UnsupportedOperationException();
}
}
private void readFully(InputStream in, byte[] b, int off, int count) throws IOException {
while(count > 0) {
int read = in.read(b, off, count);
if(read <= 0) {
throw new EOFException();
}
off += read;
count -= read;
}
}
private int readLE32(InputStream in) throws IOException {
byte[] tmp = new byte[4];
readFully(in, tmp, 0, 4);
return ((tmp[3] & 255) << 24) |
((tmp[2] & 255) << 16) |
((tmp[1] & 255) << 8) |
((tmp[0] & 255));
}
private void readFully(InputStream in, ByteBuffer buf) throws IOException {
byte[] tmp = new byte[4096];
while(buf.remaining() > 0) {
int read = in.read(tmp, 0, Math.min(tmp.length, buf.remaining()));
if(read <= 0) {
throw new EOFException();
}
buf.put(tmp, 0, read);
}
}
}