Skip to content

Commit 5e2350c

Browse files
authored
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
1 parent b32e1ae commit 5e2350c

File tree

19 files changed

+511
-19
lines changed

19 files changed

+511
-19
lines changed

jme3-core/src/main/java/com/jme3/renderer/Caps.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,16 @@ public enum Caps {
341341
*/
342342
TextureCompressionETC2,
343343

344+
/**
345+
* Supports {@link Format#BPTC} and sister formats.
346+
*/
347+
TextureCompressionBPTC,
348+
349+
/**
350+
* Supports {@link Format#RGTC1} and other RGTC compressed formats.
351+
*/
352+
TextureCompressionRGTC,
353+
344354
/**
345355
* Supports OpenGL ES 2
346356
*/

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ public interface GLExt {
101101
public static final int GL_UNSIGNED_INT_24_8_EXT = 0x84FA;
102102
public static final int GL_UNSIGNED_INT_5_9_9_9_REV_EXT = 0x8C3E;
103103
public static final int GL_WAIT_FAILED = 0x911D;
104+
105+
// OpenGL 4.2 texture compression, we now check these through the extension
106+
public static final int GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 0x8E8E;
107+
public static final int GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 0x8E8F;
108+
public static final int GL_COMPRESSED_RGBA_BPTC_UNORM = 0x8E8C;
109+
public static final int GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 0x8E8D;
104110

105111
/**
106112
* <p><a target="_blank" href="http://docs.gl/gl4/glBufferData">Reference Page</a></p>

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ public static GLImageFormat[][] getFormatsForCaps(EnumSet<Caps> caps) {
266266
formatComp(formatToGL, Format.DXT5, GLExt.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
267267
}
268268

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

282+
if(caps.contains(Caps.OpenGL42) || caps.contains(Caps.TextureCompressionBPTC)) {
283+
formatComp(formatToGL, Format.BC6H_SF16, GLExt.GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
284+
formatComp(formatToGL, Format.BC6H_UF16, GLExt.GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
285+
formatComp(formatToGL, Format.BC7_UNORM, GLExt.GL_COMPRESSED_RGBA_BPTC_UNORM, GL.GL_RGBA, GL.GL_UNSIGNED_INT);
286+
formatComp(formatToGL, Format.BC7_UNORM_SRGB, GLExt.GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL.GL_RGBA, GL.GL_UNSIGNED_INT);
287+
}
288+
282289
// Integer formats
283290
if(caps.contains(Caps.IntegerTexture)) {
284291
format(formatToGL, Format.R8I, GL3.GL_R8I, GL3.GL_RED_INTEGER, GL.GL_BYTE);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,14 @@ private void loadCapabilitiesCommon() {
395395
caps.add(Caps.TextureCompressionS3TC);
396396
}
397397

398+
if (hasExtension("GL_ARB_texture_compression_bptc")) {
399+
caps.add(Caps.TextureCompressionBPTC);
400+
}
401+
402+
if (hasExtension("GL_EXT_texture_compression_rgtc")) {
403+
caps.add(Caps.TextureCompressionRGTC);
404+
}
405+
398406
if (hasExtension("GL_ARB_ES3_compatibility")) {
399407
caps.add(Caps.TextureCompressionETC2);
400408
caps.add(Caps.TextureCompressionETC1);

jme3-core/src/main/java/com/jme3/texture/Image.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,26 @@ public enum Format {
194194

195195
SIGNED_RGTC1(4,false,true, false),
196196

197+
/**
198+
* BPTC compression BC6 signed float RGB
199+
*/
200+
BC6H_SF16(8, false, true, true),
201+
202+
/**
203+
* BPTC compression BC6 unsigned float RGB
204+
*/
205+
BC6H_UF16(8, false, true, true),
206+
207+
/**
208+
* BPTC compression BC7 RGBA
209+
*/
210+
BC7_UNORM(8, false, true, false),
211+
212+
/**
213+
* BPTC compression BC7 SRGB Alpha
214+
*/
215+
BC7_UNORM_SRGB(8, false, true, false),
216+
197217
/**
198218
* Luminance-Alpha Texture Compression.
199219
*

jme3-core/src/plugins/java/com/jme3/texture/plugins/DDSLoader.java

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ public class DDSLoader implements AssetLoader {
8484
private static final int PF_ATI1 = 0x31495441;
8585
private static final int PF_ATI2 = 0x32495441; // 0x41544932;
8686
private static final int PF_DX10 = 0x30315844; // a DX10 format
87+
private static final int PF_BC4S = 0x53344342; // a DX9 file format for BC4 signed
88+
private static final int PF_BC5S = 0x53354342; // a DX9 file format for BC5 signed
8789
private static final int DX10DIM_TEXTURE3D = 0x4;
8890
private static final int DX10MISC_TEXTURECUBE = 0x4;
8991
private static final double LOG2 = Math.log(2);
@@ -114,22 +116,17 @@ public Object load(AssetInfo info) throws IOException {
114116
throw new IllegalArgumentException("Texture assets must be loaded using a TextureKey");
115117
}
116118

117-
InputStream stream = null;
118-
try {
119-
stream = info.openStream();
119+
TextureKey textureKey = (TextureKey) info.getKey();
120+
try (InputStream stream = info.openStream()) {
120121
in = new LittleEndien(stream);
121122
loadHeader();
122123
if (texture3D) {
123-
((TextureKey) info.getKey()).setTextureTypeHint(Texture.Type.ThreeDimensional);
124+
textureKey.setTextureTypeHint(Texture.Type.ThreeDimensional);
124125
} else if (depth > 1) {
125-
((TextureKey) info.getKey()).setTextureTypeHint(Texture.Type.CubeMap);
126+
textureKey.setTextureTypeHint(Texture.Type.CubeMap);
126127
}
127-
ArrayList<ByteBuffer> data = readData(((TextureKey) info.getKey()).isFlipY());
128+
ArrayList<ByteBuffer> data = readData(textureKey.isFlipY());
128129
return new Image(pixelFormat, width, height, depth, data, sizes, ColorSpace.sRGB);
129-
} finally {
130-
if (stream != null){
131-
stream.close();
132-
}
133130
}
134131
}
135132

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

143140
private void loadDX10Header() throws IOException {
144141
int dxgiFormat = in.readInt();
145-
if (dxgiFormat == 0) {
146-
pixelFormat = Format.ETC1;
147-
bpp = 4;
148-
} else {
149-
throw new IOException("Unsupported DX10 format: " + dxgiFormat);
150-
}
142+
setPixelFormat(dxgiFormat);
143+
151144
compressed = true;
152-
145+
153146
int resDim = in.readInt();
154147
if (resDim == DX10DIM_TEXTURE3D) {
155148
texture3D = true;
@@ -166,6 +159,51 @@ private void loadDX10Header() throws IOException {
166159
in.skipBytes(4); // skip reserved value
167160
}
168161

162+
private void setPixelFormat(int dxgiFormat) throws IOException {
163+
switch(dxgiFormat) {
164+
case DXGIFormat.DXGI_FORMAT_UNKNOWN:
165+
pixelFormat = Format.ETC1;
166+
break;
167+
case DXGIFormat.DXGI_FORMAT_BC1_UNORM:
168+
pixelFormat = Format.DXT1;
169+
break;
170+
case DXGIFormat.DXGI_FORMAT_BC2_UNORM:
171+
pixelFormat = Format.DXT3;
172+
break;
173+
case DXGIFormat.DXGI_FORMAT_BC3_UNORM:
174+
pixelFormat = Format.DXT5;
175+
break;
176+
case DXGIFormat.DXGI_FORMAT_BC4_UNORM:
177+
pixelFormat = Image.Format.RGTC1;
178+
break;
179+
case DXGIFormat.DXGI_FORMAT_BC4_SNORM:
180+
pixelFormat = Format.SIGNED_RGTC1;
181+
break;
182+
case DXGIFormat.DXGI_FORMAT_BC5_UNORM:
183+
pixelFormat = Image.Format.RGTC2;
184+
break;
185+
case DXGIFormat.DXGI_FORMAT_BC5_SNORM:
186+
pixelFormat = Image.Format.SIGNED_RGTC2;
187+
break;
188+
case DXGIFormat.DXGI_FORMAT_BC6H_UF16:
189+
pixelFormat = Format.BC6H_UF16;
190+
break;
191+
case DXGIFormat.DXGI_FORMAT_BC6H_SF16:
192+
pixelFormat = Format.BC6H_SF16;
193+
break;
194+
case DXGIFormat.DXGI_FORMAT_BC7_UNORM:
195+
pixelFormat = Format.BC7_UNORM;
196+
break;
197+
case DXGIFormat.DXGI_FORMAT_BC7_UNORM_SRGB:
198+
pixelFormat = Format.BC7_UNORM_SRGB;
199+
break;
200+
default:
201+
throw new IOException("Unsupported DX10 format: " + dxgiFormat);
202+
}
203+
204+
bpp = DXGIFormat.getBitsPerPixel(dxgiFormat);
205+
}
206+
169207
/**
170208
* Reads the header (first 128 bytes) of a DDS File
171209
*/
@@ -295,6 +333,14 @@ private void readPixelFormat() throws IOException {
295333
pixelFormat = Format.Luminance16F;
296334
grayscaleOrAlpha = true;
297335
break;
336+
case PF_BC4S:
337+
bpp = 4;
338+
pixelFormat = Format.SIGNED_RGTC1;
339+
break;
340+
case PF_BC5S:
341+
bpp = 8;
342+
pixelFormat = Format.SIGNED_RGTC2;
343+
break;
298344
default:
299345
throw new IOException("Unknown fourcc: " + string(fourcc) + ", " + Integer.toHexString(fourcc));
300346
}

0 commit comments

Comments
 (0)