Skip to content

Commit 70f9da9

Browse files
Expand support for GL ES / WebGL compatible formats. (#2101)
* Add more WebGL / GLES supported formats * Add compressonator ETC formats to DDS loader * ETCFlipper description --------- Co-authored-by: SceneMax3D <[email protected]>
1 parent 9e71c73 commit 70f9da9

File tree

6 files changed

+85
-5
lines changed

6 files changed

+85
-5
lines changed

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

+5
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public interface GLExt {
4545

4646
public static final int GL_ALREADY_SIGNALED = 0x911A;
4747
public static final int GL_COMPRESSED_RGB8_ETC2 = 0x9274;
48+
public static final int GL_COMPRESSED_SRGB8_ETC2 = 0x9275;
49+
public static final int GL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
50+
public static final int GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
51+
public static final int GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
52+
public static final int GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
4853
public static final int GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
4954
public static final int GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
5055
public static final int GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;

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

+17-4
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,17 @@ public static GLImageFormat[][] getFormatsForCaps(EnumSet<Caps> caps) {
242242
// But for render buffers it's OK.
243243
format(formatToGL, Format.Depth16, GL.GL_DEPTH_COMPONENT16, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_SHORT);
244244

245-
// NOTE: OpenGL ES 2.0 does not support DEPTH_COMPONENT as internal format -- fallback to 16-bit depth.
246-
if (caps.contains(Caps.OpenGLES20)) {
245+
246+
if (caps.contains(Caps.WebGL)) {
247+
// NOTE: fallback to 24-bit depth as workaround for firefox bug in WebGL 2 where DEPTH_COMPONENT16 is not handled properly
248+
format(formatToGL, Format.Depth, GL2.GL_DEPTH_COMPONENT24, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT);
249+
} else if (caps.contains(Caps.OpenGLES20)) {
250+
// NOTE: OpenGL ES 2.0 does not support DEPTH_COMPONENT as internal format -- fallback to 16-bit depth.
247251
format(formatToGL, Format.Depth, GL.GL_DEPTH_COMPONENT16, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_SHORT);
248252
} else {
249253
format(formatToGL, Format.Depth, GL.GL_DEPTH_COMPONENT, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_BYTE);
250254
}
251-
if (caps.contains(Caps.OpenGL20) || caps.contains(Caps.Depth24)) {
255+
if (caps.contains(Caps.OpenGLES30) || caps.contains(Caps.OpenGL20) || caps.contains(Caps.Depth24)) {
252256
format(formatToGL, Format.Depth24, GL2.GL_DEPTH_COMPONENT24, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT);
253257
}
254258
if (caps.contains(Caps.FloatDepthBuffer)) {
@@ -274,11 +278,20 @@ public static GLImageFormat[][] getFormatsForCaps(EnumSet<Caps> caps) {
274278
}
275279

276280
if (caps.contains(Caps.TextureCompressionETC2)) {
281+
formatComp(formatToGL, Format.ETC2, GLExt.GL_COMPRESSED_RGBA8_ETC2_EAC, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
282+
formatComp(formatToGL, Format.ETC2_ALPHA1, GLExt.GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
277283
formatComp(formatToGL, Format.ETC1, GLExt.GL_COMPRESSED_RGB8_ETC2, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
284+
if (caps.contains(Caps.Srgb)) {
285+
formatCompSrgb(formatToGL, Format.ETC2, GLExt.GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
286+
formatCompSrgb(formatToGL, Format.ETC2_ALPHA1, GLExt.GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
287+
formatCompSrgb(formatToGL, Format.ETC1, GLExt.GL_COMPRESSED_SRGB8_ETC2, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
288+
}
278289
} else if (caps.contains(Caps.TextureCompressionETC1)) {
279-
formatComp(formatToGL, Format.ETC1, GLExt.GL_ETC1_RGB8_OES, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
290+
formatComp(formatToGL, Format.ETC1, GLExt.GL_ETC1_RGB8_OES, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
280291
}
281292

293+
294+
282295
if(caps.contains(Caps.OpenGL42) || caps.contains(Caps.TextureCompressionBPTC)) {
283296
formatComp(formatToGL, Format.BC6H_SF16, GLExt.GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
284297
formatComp(formatToGL, Format.BC6H_UF16, GLExt.GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);

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

+17
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,23 @@ public enum Format {
330330
* Requires {@link Caps#TextureCompressionETC1}.
331331
*/
332332
ETC1(4, false, true, false),
333+
334+
/**
335+
* Ericsson Texture Compression 2. Typically used on Android.
336+
* Same as {@link #ETC1} but with alpha.
337+
*
338+
* Requires {@link Caps#TextureCompressionETC2}.
339+
*/
340+
ETC2(8, false, true, false),
341+
342+
/**
343+
* Ericsson Texture Compression 2. Typically used on Android.
344+
* Same as {@link #ETC2} but alpha can be either 1 or 0.
345+
*
346+
* Requires {@link Caps#TextureCompressionETC2}.
347+
*/
348+
ETC2_ALPHA1(4, false, true, false),
349+
333350

334351
/**
335352
* 8-bit signed int red.

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

+20
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ public class DDSLoader implements AssetLoader {
8686
private static final int PF_DX10 = 0x30315844; // a DX10 format
8787
private static final int PF_BC4S = 0x53344342; // a DX9 file format for BC4 signed
8888
private static final int PF_BC5S = 0x53354342; // a DX9 file format for BC5 signed
89+
private static final int PF_ETC2_RGBA_CSN = 0x41435445; // ETC2 RGBA format notation from Compressonator
90+
private static final int PF_ETC2_RGB_CSN = 0x32435445; // ETC2 RGB format notation from Compressonator
91+
private static final int PF_ETC_RGB_CSN = 0x20435445; // ETC RGB format notation from Compressonator
92+
private static final int PF_ETC2_RGBA1_CSN = 0x50435445; // ETC RGB + Alpha1 format notation from Compressonator
8993
private static final int DX10DIM_TEXTURE3D = 0x4;
9094
private static final int DX10MISC_TEXTURECUBE = 0x4;
9195
private static final double LOG2 = Math.log(2);
@@ -341,6 +345,22 @@ private void readPixelFormat() throws IOException {
341345
bpp = 8;
342346
pixelFormat = Format.SIGNED_RGTC2;
343347
break;
348+
case PF_ETC_RGB_CSN:
349+
bpp = 4;
350+
pixelFormat = Format.ETC1;
351+
break;
352+
case PF_ETC2_RGB_CSN:
353+
bpp = 4;
354+
pixelFormat = Format.ETC1;
355+
break;
356+
case PF_ETC2_RGBA1_CSN:
357+
bpp = 4;
358+
pixelFormat = Format.ETC2_ALPHA1;
359+
break;
360+
case PF_ETC2_RGBA_CSN:
361+
bpp = 8;
362+
pixelFormat = Format.ETC2;
363+
break;
344364
default:
345365
throw new IOException("Unknown fourcc: " + string(fourcc) + ", " + Integer.toHexString(fourcc));
346366
}

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@
3636
import com.jme3.util.BufferUtils;
3737
import java.nio.ByteBuffer;
3838
import java.nio.ByteOrder;
39+
import java.util.logging.Logger;
3940

4041
/**
4142
* DXTFlipper is a utility class used to flip along Y axis DXT compressed textures.
4243
*
4344
* @author Kirill Vainer
4445
*/
4546
public class DXTFlipper {
47+
private static final Logger logger = Logger.getLogger(DXTFlipper.class.getName());
4648

4749
private static final ByteBuffer bb = ByteBuffer.allocate(8);
4850

@@ -202,7 +204,11 @@ private static void flipDXT1orDXTA3Block(byte[] block, int h){
202204
}
203205
}
204206

205-
public static ByteBuffer flipDXT(ByteBuffer img, int w, int h, Format format){
207+
public static ByteBuffer flipDXT(ByteBuffer img, int w, int h, Format format) {
208+
if (format == Format.ETC1 || format == Format.ETC2 || format == Format.ETC2_ALPHA1) {
209+
logger.warning("This is not a DXT format, but ETC. Use flipETC instead.");
210+
return ETCFlipper.flipETC(img, w, h, format);
211+
}
206212
int originalLimit = img.limit();
207213
int blocksX = (int) FastMath.ceil(w / 4f);
208214
int blocksY = (int) FastMath.ceil(h / 4f);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.jme3.texture.plugins;
2+
3+
import java.nio.ByteBuffer;
4+
import java.util.logging.Logger;
5+
6+
import com.jme3.texture.Image.Format;
7+
8+
/**
9+
* A place-holder for future implementation of ETC texture flipping.
10+
*
11+
*/
12+
public class ETCFlipper {
13+
private static final Logger logger = Logger.getLogger(ETCFlipper.class.getName());
14+
15+
public static ByteBuffer flipETC(ByteBuffer img, int w, int h, Format format) {
16+
logger.warning("ETC texture flipping is not supported yet");
17+
return img;
18+
}
19+
}

0 commit comments

Comments
 (0)