Skip to content

Commit

Permalink
Expand support for GL ES / WebGL compatible formats. (#2101)
Browse files Browse the repository at this point in the history
* Add more WebGL / GLES supported formats

* Add compressonator ETC formats to DDS loader

* ETCFlipper description

---------

Co-authored-by: SceneMax3D <[email protected]>
  • Loading branch information
riccardobl and scenemax3d authored Jan 19, 2024
1 parent 9e71c73 commit 70f9da9
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 5 deletions.
5 changes: 5 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 @@ -45,6 +45,11 @@ public interface GLExt {

public static final int GL_ALREADY_SIGNALED = 0x911A;
public static final int GL_COMPRESSED_RGB8_ETC2 = 0x9274;
public static final int GL_COMPRESSED_SRGB8_ETC2 = 0x9275;
public static final int GL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
public static final int GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
public static final int GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
public static final int GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
public static final int GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
public static final int GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
public static final int GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,17 @@ public static GLImageFormat[][] getFormatsForCaps(EnumSet<Caps> caps) {
// But for render buffers it's OK.
format(formatToGL, Format.Depth16, GL.GL_DEPTH_COMPONENT16, GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_SHORT);

// NOTE: OpenGL ES 2.0 does not support DEPTH_COMPONENT as internal format -- fallback to 16-bit depth.
if (caps.contains(Caps.OpenGLES20)) {

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

if (caps.contains(Caps.TextureCompressionETC2)) {
formatComp(formatToGL, Format.ETC2, GLExt.GL_COMPRESSED_RGBA8_ETC2_EAC, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
formatComp(formatToGL, Format.ETC2_ALPHA1, GLExt.GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
formatComp(formatToGL, Format.ETC1, GLExt.GL_COMPRESSED_RGB8_ETC2, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
if (caps.contains(Caps.Srgb)) {
formatCompSrgb(formatToGL, Format.ETC2, GLExt.GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
formatCompSrgb(formatToGL, Format.ETC2_ALPHA1, GLExt.GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
formatCompSrgb(formatToGL, Format.ETC1, GLExt.GL_COMPRESSED_SRGB8_ETC2, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
}
} else if (caps.contains(Caps.TextureCompressionETC1)) {
formatComp(formatToGL, Format.ETC1, GLExt.GL_ETC1_RGB8_OES, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
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);
Expand Down
17 changes: 17 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 @@ -330,6 +330,23 @@ public enum Format {
* Requires {@link Caps#TextureCompressionETC1}.
*/
ETC1(4, false, true, false),

/**
* Ericsson Texture Compression 2. Typically used on Android.
* Same as {@link #ETC1} but with alpha.
*
* Requires {@link Caps#TextureCompressionETC2}.
*/
ETC2(8, false, true, false),

/**
* Ericsson Texture Compression 2. Typically used on Android.
* Same as {@link #ETC2} but alpha can be either 1 or 0.
*
* Requires {@link Caps#TextureCompressionETC2}.
*/
ETC2_ALPHA1(4, false, true, false),


/**
* 8-bit signed int red.
Expand Down
20 changes: 20 additions & 0 deletions jme3-core/src/plugins/java/com/jme3/texture/plugins/DDSLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ public class DDSLoader implements AssetLoader {
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 PF_ETC2_RGBA_CSN = 0x41435445; // ETC2 RGBA format notation from Compressonator
private static final int PF_ETC2_RGB_CSN = 0x32435445; // ETC2 RGB format notation from Compressonator
private static final int PF_ETC_RGB_CSN = 0x20435445; // ETC RGB format notation from Compressonator
private static final int PF_ETC2_RGBA1_CSN = 0x50435445; // ETC RGB + Alpha1 format notation from Compressonator
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 @@ -341,6 +345,22 @@ private void readPixelFormat() throws IOException {
bpp = 8;
pixelFormat = Format.SIGNED_RGTC2;
break;
case PF_ETC_RGB_CSN:
bpp = 4;
pixelFormat = Format.ETC1;
break;
case PF_ETC2_RGB_CSN:
bpp = 4;
pixelFormat = Format.ETC1;
break;
case PF_ETC2_RGBA1_CSN:
bpp = 4;
pixelFormat = Format.ETC2_ALPHA1;
break;
case PF_ETC2_RGBA_CSN:
bpp = 8;
pixelFormat = Format.ETC2;
break;
default:
throw new IOException("Unknown fourcc: " + string(fourcc) + ", " + Integer.toHexString(fourcc));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@
import com.jme3.util.BufferUtils;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.logging.Logger;

/**
* DXTFlipper is a utility class used to flip along Y axis DXT compressed textures.
*
* @author Kirill Vainer
*/
public class DXTFlipper {
private static final Logger logger = Logger.getLogger(DXTFlipper.class.getName());

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

Expand Down Expand Up @@ -202,7 +204,11 @@ private static void flipDXT1orDXTA3Block(byte[] block, int h){
}
}

public static ByteBuffer flipDXT(ByteBuffer img, int w, int h, Format format){
public static ByteBuffer flipDXT(ByteBuffer img, int w, int h, Format format) {
if (format == Format.ETC1 || format == Format.ETC2 || format == Format.ETC2_ALPHA1) {
logger.warning("This is not a DXT format, but ETC. Use flipETC instead.");
return ETCFlipper.flipETC(img, w, h, format);
}
int originalLimit = img.limit();
int blocksX = (int) FastMath.ceil(w / 4f);
int blocksY = (int) FastMath.ceil(h / 4f);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.jme3.texture.plugins;

import java.nio.ByteBuffer;
import java.util.logging.Logger;

import com.jme3.texture.Image.Format;

/**
* A place-holder for future implementation of ETC texture flipping.
*
*/
public class ETCFlipper {
private static final Logger logger = Logger.getLogger(ETCFlipper.class.getName());

public static ByteBuffer flipETC(ByteBuffer img, int w, int h, Format format) {
logger.warning("ETC texture flipping is not supported yet");
return img;
}
}

0 comments on commit 70f9da9

Please sign in to comment.