Skip to content
10 changes: 10 additions & 0 deletions jme3-core/src/main/java/com/jme3/renderer/Caps.java
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,16 @@ public enum Caps {
*/
TextureCompressionETC2,

/**
* Supports {@link Format#BPTC} and sister formats.
*/
TextureCompressionBPTC,

/**
* Supports {@link Format#RGTC1} and other RGTC compressed formats.
*/
TextureCompressionRGTC,

/**
* Supports OpenGL ES 2
*/
Expand Down
6 changes: 6 additions & 0 deletions jme3-core/src/main/java/com/jme3/renderer/opengl/GLExt.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ public interface GLExt {
public static final int GL_UNSIGNED_INT_24_8_EXT = 0x84FA;
public static final int GL_UNSIGNED_INT_5_9_9_9_REV_EXT = 0x8C3E;
public static final int GL_WAIT_FAILED = 0x911D;

// OpenGL 4.2 texture compression, we now check these through the extension
public static final int GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 0x8E8E;
public static final int GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 0x8E8F;
public static final int GL_COMPRESSED_RGBA_BPTC_UNORM = 0x8E8C;
public static final int GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 0x8E8D;

/**
* <p><a target="_blank" href="http://docs.gl/gl4/glBufferData">Reference Page</a></p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public static GLImageFormat[][] getFormatsForCaps(EnumSet<Caps> caps) {
formatComp(formatToGL, Format.DXT5, GLExt.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
}

if(caps.contains(Caps.OpenGL30)){
if(caps.contains(Caps.OpenGL30) || caps.contains(Caps.TextureCompressionRGTC)){
formatComp(formatToGL, Format.RGTC2, GL3.GL_COMPRESSED_RG_RGTC2, GL3.GL_RG, GL.GL_UNSIGNED_BYTE);
formatComp(formatToGL, Format.SIGNED_RGTC2, GL3.GL_COMPRESSED_SIGNED_RG_RGTC2, GL3.GL_RG, GL.GL_BYTE);
formatComp(formatToGL, Format.RGTC1, GL3.GL_COMPRESSED_RED_RGTC1, GL3.GL_RED, GL.GL_UNSIGNED_BYTE);
Expand All @@ -279,6 +279,13 @@ public static GLImageFormat[][] getFormatsForCaps(EnumSet<Caps> caps) {
formatComp(formatToGL, Format.ETC1, GLExt.GL_ETC1_RGB8_OES, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
}

if(caps.contains(Caps.OpenGL42) || caps.contains(Caps.TextureCompressionBPTC)) {
formatComp(formatToGL, Format.BC6H_SF16, GLExt.GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
formatComp(formatToGL, Format.BC6H_UF16, GLExt.GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
formatComp(formatToGL, Format.BC7_UNORM, GLExt.GL_COMPRESSED_RGBA_BPTC_UNORM, GL.GL_RGBA, GL.GL_UNSIGNED_INT);
formatComp(formatToGL, Format.BC7_UNORM_SRGB, GLExt.GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL.GL_RGBA, GL.GL_UNSIGNED_INT);
}

// Integer formats
if(caps.contains(Caps.IntegerTexture)) {
format(formatToGL, Format.R8I, GL3.GL_R8I, GL3.GL_RED_INTEGER, GL.GL_BYTE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,14 @@ private void loadCapabilitiesCommon() {
caps.add(Caps.TextureCompressionS3TC);
}

if (hasExtension("GL_ARB_texture_compression_bptc")) {
caps.add(Caps.TextureCompressionBPTC);
}

if (hasExtension("GL_EXT_texture_compression_rgtc")) {
caps.add(Caps.TextureCompressionRGTC);
}

if (hasExtension("GL_ARB_ES3_compatibility")) {
caps.add(Caps.TextureCompressionETC2);
caps.add(Caps.TextureCompressionETC1);
Expand Down
20 changes: 20 additions & 0 deletions jme3-core/src/main/java/com/jme3/texture/Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,26 @@ public enum Format {

SIGNED_RGTC1(4,false,true, false),

/**
* BPTC compression BC6 signed float RGB
*/
BC6H_SF16(8, false, true, true),

/**
* BPTC compression BC6 unsigned float RGB
*/
BC6H_UF16(8, false, true, true),

/**
* BPTC compression BC7 RGBA
*/
BC7_UNORM(8, false, true, false),

/**
* BPTC compression BC7 SRGB Alpha
*/
BC7_UNORM_SRGB(8, false, true, false),

/**
* Luminance-Alpha Texture Compression.
*
Expand Down
80 changes: 63 additions & 17 deletions jme3-core/src/plugins/java/com/jme3/texture/plugins/DDSLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ public class DDSLoader implements AssetLoader {
private static final int PF_ATI1 = 0x31495441;
private static final int PF_ATI2 = 0x32495441; // 0x41544932;
private static final int PF_DX10 = 0x30315844; // a DX10 format
private static final int PF_BC4S = 0x53344342; // a DX9 file format for BC4 signed
private static final int PF_BC5S = 0x53354342; // a DX9 file format for BC5 signed
private static final int DX10DIM_TEXTURE3D = 0x4;
private static final int DX10MISC_TEXTURECUBE = 0x4;
private static final double LOG2 = Math.log(2);
Expand Down Expand Up @@ -114,22 +116,17 @@ public Object load(AssetInfo info) throws IOException {
throw new IllegalArgumentException("Texture assets must be loaded using a TextureKey");
}

InputStream stream = null;
try {
stream = info.openStream();
TextureKey textureKey = (TextureKey) info.getKey();
try (InputStream stream = info.openStream()) {
in = new LittleEndien(stream);
loadHeader();
if (texture3D) {
((TextureKey) info.getKey()).setTextureTypeHint(Texture.Type.ThreeDimensional);
textureKey.setTextureTypeHint(Texture.Type.ThreeDimensional);
} else if (depth > 1) {
((TextureKey) info.getKey()).setTextureTypeHint(Texture.Type.CubeMap);
textureKey.setTextureTypeHint(Texture.Type.CubeMap);
}
ArrayList<ByteBuffer> data = readData(((TextureKey) info.getKey()).isFlipY());
ArrayList<ByteBuffer> data = readData(textureKey.isFlipY());
return new Image(pixelFormat, width, height, depth, data, sizes, ColorSpace.sRGB);
} finally {
if (stream != null){
stream.close();
}
}
}

Expand All @@ -142,14 +139,10 @@ public Image load(InputStream stream) throws IOException {

private void loadDX10Header() throws IOException {
int dxgiFormat = in.readInt();
if (dxgiFormat == 0) {
pixelFormat = Format.ETC1;
bpp = 4;
} else {
throw new IOException("Unsupported DX10 format: " + dxgiFormat);
}
setPixelFormat(dxgiFormat);

compressed = true;

int resDim = in.readInt();
if (resDim == DX10DIM_TEXTURE3D) {
texture3D = true;
Expand All @@ -166,6 +159,51 @@ private void loadDX10Header() throws IOException {
in.skipBytes(4); // skip reserved value
}

private void setPixelFormat(int dxgiFormat) throws IOException {
switch(dxgiFormat) {
case DXGIFormat.DXGI_FORMAT_UNKNOWN:
pixelFormat = Format.ETC1;
break;
case DXGIFormat.DXGI_FORMAT_BC1_UNORM:
pixelFormat = Format.DXT1;
break;
case DXGIFormat.DXGI_FORMAT_BC2_UNORM:
pixelFormat = Format.DXT3;
break;
case DXGIFormat.DXGI_FORMAT_BC3_UNORM:
pixelFormat = Format.DXT5;
break;
case DXGIFormat.DXGI_FORMAT_BC4_UNORM:
pixelFormat = Image.Format.RGTC1;
break;
case DXGIFormat.DXGI_FORMAT_BC4_SNORM:
pixelFormat = Format.SIGNED_RGTC1;
break;
case DXGIFormat.DXGI_FORMAT_BC5_UNORM:
pixelFormat = Image.Format.RGTC2;
break;
case DXGIFormat.DXGI_FORMAT_BC5_SNORM:
pixelFormat = Image.Format.SIGNED_RGTC2;
break;
case DXGIFormat.DXGI_FORMAT_BC6H_UF16:
pixelFormat = Format.BC6H_UF16;
break;
case DXGIFormat.DXGI_FORMAT_BC6H_SF16:
pixelFormat = Format.BC6H_SF16;
break;
case DXGIFormat.DXGI_FORMAT_BC7_UNORM:
pixelFormat = Format.BC7_UNORM;
break;
case DXGIFormat.DXGI_FORMAT_BC7_UNORM_SRGB:
pixelFormat = Format.BC7_UNORM_SRGB;
break;
default:
throw new IOException("Unsupported DX10 format: " + dxgiFormat);
}

bpp = DXGIFormat.getBitsPerPixel(dxgiFormat);
}

/**
* Reads the header (first 128 bytes) of a DDS File
*/
Expand Down Expand Up @@ -295,6 +333,14 @@ private void readPixelFormat() throws IOException {
pixelFormat = Format.Luminance16F;
grayscaleOrAlpha = true;
break;
case PF_BC4S:
bpp = 4;
pixelFormat = Format.SIGNED_RGTC1;
break;
case PF_BC5S:
bpp = 8;
pixelFormat = Format.SIGNED_RGTC2;
break;
default:
throw new IOException("Unknown fourcc: " + string(fourcc) + ", " + Integer.toHexString(fourcc));
}
Expand Down
Loading