Selaa lähdekoodia

solve issue 1619 (add texture-compression formats) (#1621)

* Added the DXGI format constants

* Support BPTC formats

* Add the BPTC format capabilities

* Add the BPTC formats

* Try with resources

* Fix BC6 bpp values

* Properly support BC4 and BC5 file formats

* Better error message

* Also accept OpenGL 4.2 to support BPTC compression

* Add getter for block size (for flipping etc)

* Better constant names

* Added load test for various texture formats stored in DDS files
Toni Helenius 3 vuotta sitten
vanhempi
commit
5e2350cc5a

+ 10 - 0
jme3-core/src/main/java/com/jme3/renderer/Caps.java

@@ -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
      */

+ 6 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GLExt.java

@@ -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>

+ 8 - 1
jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java

@@ -266,7 +266,7 @@ public final class GLImageFormats {
             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);
@@ -279,6 +279,13 @@ public final class GLImageFormats {
             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);

+ 8 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

@@ -395,6 +395,14 @@ public final class GLRenderer implements Renderer {
             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);

+ 20 - 0
jme3-core/src/main/java/com/jme3/texture/Image.java

@@ -194,6 +194,26 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ {
         
         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. 
          * 

+ 63 - 17
jme3-core/src/plugins/java/com/jme3/texture/plugins/DDSLoader.java

@@ -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);
@@ -114,22 +116,17 @@ public class DDSLoader implements AssetLoader {
             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();
-            }
         }
     }
 
@@ -142,14 +139,10 @@ public class DDSLoader implements AssetLoader {
 
     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;
@@ -166,6 +159,51 @@ public class DDSLoader implements AssetLoader {
         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
      */
@@ -295,6 +333,14 @@ public class DDSLoader implements AssetLoader {
                     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));
             }

+ 300 - 0
jme3-core/src/plugins/java/com/jme3/texture/plugins/DXGIFormat.java

@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2009-2021 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.texture.plugins;
+
+/**
+ * Holds the constants for DXGI format defined in DDS file
+ * 
+ * @author Toni Helenius
+ */
+final class DXGIFormat {
+
+    static final int DXGI_FORMAT_UNKNOWN = 0x00;
+    static final int DXGI_FORMAT_R32G32B32A32_TYPELESS = 0x01;
+    static final int DXGI_FORMAT_R32G32B32A32_FLOAT = 0x02;
+    static final int DXGI_FORMAT_R32G32B32A32_UINT = 0x03;
+    static final int DXGI_FORMAT_R32G32B32A32_SINT = 0x04;
+    static final int DXGI_FORMAT_R32G32B32_TYPELESS = 0x05;
+    static final int DXGI_FORMAT_R32G32B32_FLOAT = 0x06;
+    static final int DXGI_FORMAT_R32G32B32_UINT = 0x07;
+    static final int DXGI_FORMAT_R32G32B32_SINT = 0x08;
+    static final int DXGI_FORMAT_R16G16B16A16_TYPELESS = 0x09;
+    static final int DXGI_FORMAT_R16G16B16A16_FLOAT = 0x0A;
+    static final int DXGI_FORMAT_R16G16B16A16_UNORM = 0x0B;
+    static final int DXGI_FORMAT_R16G16B16A16_UINT = 0x0C;
+    static final int DXGI_FORMAT_R16G16B16A16_SNORM = 0x0D;
+    static final int DXGI_FORMAT_R16G16B16A16_SINT = 0x0E;
+    static final int DXGI_FORMAT_R32G32_TYPELESS = 0x0F;
+    static final int DXGI_FORMAT_R32G32_FLOAT = 0x10;
+    static final int DXGI_FORMAT_R32G32_UINT = 0x11;
+    static final int DXGI_FORMAT_R32G32_SINT = 0x12;
+    static final int DXGI_FORMAT_R32G8X24_TYPELESS = 0x13;
+    static final int DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 0x14;
+    static final int DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 0x15;
+    static final int DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 0x16;
+    static final int DXGI_FORMAT_R10G10B10A2_TYPELESS = 0x17;
+    static final int DXGI_FORMAT_R10G10B10A2_UNORM = 0x18;
+    static final int DXGI_FORMAT_R10G10B10A2_UINT = 0x19;
+    static final int DXGI_FORMAT_R11G11B10_FLOAT = 0x1A;
+    static final int DXGI_FORMAT_R8G8B8A8_TYPELESS = 0x1B;
+    static final int DXGI_FORMAT_R8G8B8A8_UNORM = 0x1C;
+    static final int DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 0x1D;
+    static final int DXGI_FORMAT_R8G8B8A8_UINT = 0x1E;
+    static final int DXGI_FORMAT_R8G8B8A8_SNORM = 0x1F;
+    static final int DXGI_FORMAT_R8G8B8A8_SINT = 0x20;
+    static final int DXGI_FORMAT_R16G16_TYPELESS = 0x21;
+    static final int DXGI_FORMAT_R16G16_FLOAT = 0x22;
+    static final int DXGI_FORMAT_R16G16_UNORM = 0x23;
+    static final int DXGI_FORMAT_R16G16_UINT = 0x24;
+    static final int DXGI_FORMAT_R16G16_SNORM = 0x25;
+    static final int DXGI_FORMAT_R16G16_SINT = 0x26;
+    static final int DXGI_FORMAT_R32_TYPELESS = 0x27;
+    static final int DXGI_FORMAT_D32_FLOAT = 0x28;
+    static final int DXGI_FORMAT_R32_FLOAT = 0x29;
+    static final int DXGI_FORMAT_R32_UINT = 0x2A;
+    static final int DXGI_FORMAT_R32_SINT = 0x2B;
+    static final int DXGI_FORMAT_R24G8_TYPELESS = 0x2C;
+    static final int DXGI_FORMAT_D24_UNORM_S8_UINT = 0x2D;
+    static final int DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 0x2E;
+    static final int DXGI_FORMAT_X24_TYPELESS_G8_UINT = 0x2F;
+    static final int DXGI_FORMAT_R8G8_TYPELESS = 0x30;
+    static final int DXGI_FORMAT_R8G8_UNORM = 0x31;
+    static final int DXGI_FORMAT_R8G8_UINT = 0x32;
+    static final int DXGI_FORMAT_R8G8_SNORM = 0x33;
+    static final int DXGI_FORMAT_R8G8_SINT = 0x34;
+    static final int DXGI_FORMAT_R16_TYPELESS = 0x35;
+    static final int DXGI_FORMAT_R16_FLOAT = 0x36;
+    static final int DXGI_FORMAT_D16_UNORM = 0x37;
+    static final int DXGI_FORMAT_R16_UNORM = 0x38;
+    static final int DXGI_FORMAT_R16_UINT = 0x39;
+    static final int DXGI_FORMAT_R16_SNORM = 0x3A;
+    static final int DXGI_FORMAT_R16_SINT = 0x3B;
+    static final int DXGI_FORMAT_R8_TYPELESS = 0x3C;
+    static final int DXGI_FORMAT_R8_UNORM = 0x3D;
+    static final int DXGI_FORMAT_R8_UINT = 0x3E;
+    static final int DXGI_FORMAT_R8_SNORM = 0x3F;
+    static final int DXGI_FORMAT_R8_SINT = 0x40;
+    static final int DXGI_FORMAT_A8_UNORM = 0x41;
+    static final int DXGI_FORMAT_R1_UNORM = 0x42;
+    static final int DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 0x43;
+    static final int DXGI_FORMAT_R8G8_B8G8_UNORM = 0x44;
+    static final int DXGI_FORMAT_G8R8_G8B8_UNORM = 0x45;
+    static final int DXGI_FORMAT_BC1_TYPELESS = 0x46;
+    static final int DXGI_FORMAT_BC1_UNORM = 0x47;
+    static final int DXGI_FORMAT_BC1_UNORM_SRGB = 0x48;
+    static final int DXGI_FORMAT_BC2_TYPELESS = 0x49;
+    static final int DXGI_FORMAT_BC2_UNORM = 0x4A;
+    static final int DXGI_FORMAT_BC2_UNORM_SRGB = 0x4B;
+    static final int DXGI_FORMAT_BC3_TYPELESS = 0x4C;
+    static final int DXGI_FORMAT_BC3_UNORM = 0x4D;
+    static final int DXGI_FORMAT_BC3_UNORM_SRGB = 0x4E;
+    static final int DXGI_FORMAT_BC4_TYPELESS = 0x4F;
+    static final int DXGI_FORMAT_BC4_UNORM = 0x50;
+    static final int DXGI_FORMAT_BC4_SNORM = 0x51;
+    static final int DXGI_FORMAT_BC5_TYPELESS = 0x52;
+    static final int DXGI_FORMAT_BC5_UNORM = 0x53;
+    static final int DXGI_FORMAT_BC5_SNORM = 0x54;
+    static final int DXGI_FORMAT_B5G6R5_UNORM = 0x55;
+    static final int DXGI_FORMAT_B5G5R5A1_UNORM = 0x56;
+    static final int DXGI_FORMAT_B8G8R8A8_UNORM = 0x57;
+    static final int DXGI_FORMAT_B8G8R8X8_UNORM = 0x58;
+    static final int DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 0x59;
+    static final int DXGI_FORMAT_B8G8R8A8_TYPELESS = 0x5A;
+    static final int DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 0x5B;
+    static final int DXGI_FORMAT_B8G8R8X8_TYPELESS = 0x5C;
+    static final int DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 0x5D;
+    static final int DXGI_FORMAT_BC6H_TYPELESS = 0x5E;
+    static final int DXGI_FORMAT_BC6H_UF16 = 0x5F;
+    static final int DXGI_FORMAT_BC6H_SF16 = 0x60;
+    static final int DXGI_FORMAT_BC7_TYPELESS = 0x61;
+    static final int DXGI_FORMAT_BC7_UNORM = 0x62;
+    static final int DXGI_FORMAT_BC7_UNORM_SRGB = 0x63;
+    static final int DXGI_FORMAT_AYUV = 0x64;
+    static final int DXGI_FORMAT_Y410 = 0x65;
+    static final int DXGI_FORMAT_Y416 = 0x66;
+    static final int DXGI_FORMAT_NV12 = 0x67;
+    static final int DXGI_FORMAT_P010 = 0x68;
+    static final int DXGI_FORMAT_P016 = 0x69;
+    static final int DXGI_FORMAT_420_OPAQUE = 0x6A;
+    static final int DXGI_FORMAT_YUY2 = 0x6B;
+    static final int DXGI_FORMAT_Y210 = 0x6C;
+    static final int DXGI_FORMAT_Y216 = 0x6D;
+    static final int DXGI_FORMAT_NV11 = 0x6E;
+    static final int DXGI_FORMAT_AI44 = 0x6F;
+    static final int DXGI_FORMAT_IA44 = 0x70;
+    static final int DXGI_FORMAT_P8 = 0x71;
+    static final int DXGI_FORMAT_A8P8 = 0x72;
+    static final int DXGI_FORMAT_B4G4R4A4_UNORM = 0x73;
+    static final int DXGI_FORMAT_P208 = 0x74;
+    static final int DXGI_FORMAT_V208 = 0x75;
+    static final int DXGI_FORMAT_V408 = 0x76;
+    static final int DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 0x77;
+    static final int DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 0x78;
+    static final int DXGI_FORMAT_FORCE_UINT = 0x79;
+
+    static int getBitsPerPixel(int dxgiFormat) {
+        switch (dxgiFormat) {
+            case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+            case DXGI_FORMAT_R32G32B32A32_FLOAT:
+            case DXGI_FORMAT_R32G32B32A32_UINT:
+            case DXGI_FORMAT_R32G32B32A32_SINT:
+                return 128;
+
+            case DXGI_FORMAT_R32G32B32_TYPELESS:
+            case DXGI_FORMAT_R32G32B32_FLOAT:
+            case DXGI_FORMAT_R32G32B32_UINT:
+            case DXGI_FORMAT_R32G32B32_SINT:
+                return 96;
+
+            case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+            case DXGI_FORMAT_R16G16B16A16_FLOAT:
+            case DXGI_FORMAT_R16G16B16A16_UNORM:
+            case DXGI_FORMAT_R16G16B16A16_UINT:
+            case DXGI_FORMAT_R16G16B16A16_SNORM:
+            case DXGI_FORMAT_R16G16B16A16_SINT:
+            case DXGI_FORMAT_R32G32_TYPELESS:
+            case DXGI_FORMAT_R32G32_FLOAT:
+            case DXGI_FORMAT_R32G32_UINT:
+            case DXGI_FORMAT_R32G32_SINT:
+            case DXGI_FORMAT_R32G8X24_TYPELESS:
+            case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+            case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+            case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+                return 64;
+
+            case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+            case DXGI_FORMAT_R10G10B10A2_UNORM:
+            case DXGI_FORMAT_R10G10B10A2_UINT:
+            case DXGI_FORMAT_R11G11B10_FLOAT:
+            case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+            case DXGI_FORMAT_R8G8B8A8_UNORM:
+            case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+            case DXGI_FORMAT_R8G8B8A8_UINT:
+            case DXGI_FORMAT_R8G8B8A8_SNORM:
+            case DXGI_FORMAT_R8G8B8A8_SINT:
+            case DXGI_FORMAT_R16G16_TYPELESS:
+            case DXGI_FORMAT_R16G16_FLOAT:
+            case DXGI_FORMAT_R16G16_UNORM:
+            case DXGI_FORMAT_R16G16_UINT:
+            case DXGI_FORMAT_R16G16_SNORM:
+            case DXGI_FORMAT_R16G16_SINT:
+            case DXGI_FORMAT_R32_TYPELESS:
+            case DXGI_FORMAT_D32_FLOAT:
+            case DXGI_FORMAT_R32_FLOAT:
+            case DXGI_FORMAT_R32_UINT:
+            case DXGI_FORMAT_R32_SINT:
+            case DXGI_FORMAT_R24G8_TYPELESS:
+            case DXGI_FORMAT_D24_UNORM_S8_UINT:
+            case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+            case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+            case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+            case DXGI_FORMAT_R8G8_B8G8_UNORM:
+            case DXGI_FORMAT_G8R8_G8B8_UNORM:
+            case DXGI_FORMAT_B8G8R8A8_UNORM:
+            case DXGI_FORMAT_B8G8R8X8_UNORM:
+            case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+            case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+            case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+            case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+            case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+                return 32;
+
+            case DXGI_FORMAT_R8G8_TYPELESS:
+            case DXGI_FORMAT_R8G8_UNORM:
+            case DXGI_FORMAT_R8G8_UINT:
+            case DXGI_FORMAT_R8G8_SNORM:
+            case DXGI_FORMAT_R8G8_SINT:
+            case DXGI_FORMAT_R16_TYPELESS:
+            case DXGI_FORMAT_R16_FLOAT:
+            case DXGI_FORMAT_D16_UNORM:
+            case DXGI_FORMAT_R16_UNORM:
+            case DXGI_FORMAT_R16_UINT:
+            case DXGI_FORMAT_R16_SNORM:
+            case DXGI_FORMAT_R16_SINT:
+            case DXGI_FORMAT_B5G6R5_UNORM:
+            case DXGI_FORMAT_B5G5R5A1_UNORM:
+            case DXGI_FORMAT_B4G4R4A4_UNORM:
+                return 16;
+
+            case DXGI_FORMAT_R8_TYPELESS:
+            case DXGI_FORMAT_R8_UNORM:
+            case DXGI_FORMAT_R8_UINT:
+            case DXGI_FORMAT_R8_SNORM:
+            case DXGI_FORMAT_R8_SINT:
+            case DXGI_FORMAT_A8_UNORM:
+                return 8;
+
+            case DXGI_FORMAT_R1_UNORM:
+                return 1;
+
+            case DXGI_FORMAT_BC1_TYPELESS:
+            case DXGI_FORMAT_BC1_UNORM:
+            case DXGI_FORMAT_BC1_UNORM_SRGB:
+            case DXGI_FORMAT_BC4_TYPELESS:
+            case DXGI_FORMAT_BC4_UNORM:
+            case DXGI_FORMAT_BC4_SNORM:
+                return 4;
+
+            case DXGI_FORMAT_BC2_TYPELESS:
+            case DXGI_FORMAT_BC2_UNORM:
+            case DXGI_FORMAT_BC2_UNORM_SRGB:
+            case DXGI_FORMAT_BC3_TYPELESS:
+            case DXGI_FORMAT_BC3_UNORM:
+            case DXGI_FORMAT_BC3_UNORM_SRGB:
+            case DXGI_FORMAT_BC5_TYPELESS:
+            case DXGI_FORMAT_BC5_UNORM:
+            case DXGI_FORMAT_BC5_SNORM:
+            case DXGI_FORMAT_BC6H_TYPELESS:
+            case DXGI_FORMAT_BC6H_UF16:
+            case DXGI_FORMAT_BC6H_SF16:
+            case DXGI_FORMAT_BC7_TYPELESS:
+            case DXGI_FORMAT_BC7_UNORM:
+            case DXGI_FORMAT_BC7_UNORM_SRGB:
+                return 8;
+
+            default:
+                return 0;
+        }
+    }
+    
+    static int getBlockSize(int dxgiFormat) {
+        switch (dxgiFormat) {
+            case DXGI_FORMAT_BC1_UNORM:
+            case DXGI_FORMAT_BC4_UNORM:
+            case DXGI_FORMAT_BC4_SNORM:
+                return 8;
+        }
+        
+        return 16;
+    }
+
+    }

+ 1 - 1
jme3-core/src/plugins/java/com/jme3/texture/plugins/DXTFlipper.java

@@ -226,7 +226,7 @@ public class DXTFlipper {
                 type = 5;
                 break;
             default:
-                throw new IllegalArgumentException();
+                throw new IllegalArgumentException("No flip support for texture format " + format);
         }
 
         // DXT1 uses 8 bytes per block,

+ 95 - 0
jme3-examples/src/main/java/jme3test/texture/dds/TestLoadDds.java

@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2009-2021 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jme3test.texture.dds;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.asset.TextureKey;
+import com.jme3.math.ColorRGBA;
+import com.jme3.renderer.RenderManager;
+import com.jme3.texture.Texture2D;
+import com.jme3.texture.plugins.DDSLoader;
+import com.jme3.ui.Picture;
+
+/**
+ * Test various supported BC* textures in DDS file format
+ * 
+ * @author Toni Helenius
+ */
+public class TestLoadDds extends SimpleApplication {
+
+    public static void main(String[] args) {
+        TestLoadDds app = new TestLoadDds();
+        //app.setShowSettings(false);
+        app.start();
+    }
+   
+    @Override
+    public void simpleInitApp() {
+        viewPort.setBackgroundColor(ColorRGBA.DarkGray);
+        assetManager.registerLoader(DDSLoader.class, "dds");
+           
+        loadTexture(0, "Textures/dds/Monkey_PNG_BC7_1.DDS", "BC7");
+        loadTexture(1, "Textures/dds/Monkey_PNG_BC6H_3.DDS", "BC6");
+        loadTexture(2, "Textures/dds/Monkey_PNG_BC6H_SF_2.DDS", "BC6_SF");
+        loadTexture(3, "Textures/dds/Monkey_PNG_BC5_S_6.DDS", "BC5_S");
+        loadTexture(4, "Textures/dds/Monkey_PNG_BC5_7.DDS", "BC5");
+        loadTexture(5, "Textures/dds/Monkey_PNG_BC4_S_8.DDS", "BC4_S");
+        loadTexture(6, "Textures/dds/Monkey_PNG_BC4_9.DDS", "BC4");
+        loadTexture(7, "Textures/dds/Monkey_PNG_BC3_10.DDS", "BC3");
+        loadTexture(8, "Textures/dds/Monkey_PNG_BC2_11.DDS", "BC2");
+        loadTexture(9, "Textures/dds/Monkey_PNG_BC1_12.DDS", "BC1");
+        
+        flyCam.setDragToRotate(true);
+               
+    }
+
+    private void loadTexture(int index, String texture, String description) {
+        Texture2D t = (Texture2D)assetManager.loadTexture(new TextureKey(texture, false));
+        Picture p = new Picture(description, true);
+        p.setTexture(assetManager, t, false);
+        p.setLocalTranslation((index % 4) * 200, Math.floorDiv(index, 4) * 200, 0);
+        p.setWidth(200);
+        p.setHeight(200);
+        guiNode.attachChild(p);
+    }
+    
+    
+    @Override
+    public void simpleUpdate(float tpf) {
+        //TODO: add update code
+    }
+
+    @Override
+    public void simpleRender(RenderManager rm) {
+        //TODO: add render code
+    }
+}

BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC1_12.DDS


BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC2_11.DDS


BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC3_10.DDS


BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC4_9.DDS


BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC4_S_8.DDS


BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC5_7.DDS


BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC5_S_6.DDS


BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC6H_3.DDS


BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC6H_SF_2.DDS


BIN
jme3-testdata/src/main/resources/Textures/dds/Monkey_PNG_BC7_1.DDS