diff --git a/jme3-core/src/main/java/com/jme3/renderer/Caps.java b/jme3-core/src/main/java/com/jme3/renderer/Caps.java index d4a7ae79e..f698859d2 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Caps.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Caps.java @@ -251,7 +251,12 @@ public enum Caps { /** * Supports anisotropic texture filtering. */ - TextureFilterAnisotropic; + TextureFilterAnisotropic, + + /** + * Supports {@link Format#ETC1} texture compression. + */ + TextureCompressionETC1; /** * Returns true if given the renderer capabilities, the texture diff --git a/jme3-core/src/main/java/com/jme3/texture/Image.java b/jme3-core/src/main/java/com/jme3/texture/Image.java index 42cbdfb10..3916d1800 100644 --- a/jme3-core/src/main/java/com/jme3/texture/Image.java +++ b/jme3-core/src/main/java/com/jme3/texture/Image.java @@ -317,7 +317,14 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ { * It is also a required format, so you can count on it * being present. */ - RGB10_A2(32, false); + RGB10_A2(32, false), + + /** + * Ericsson Texture Compression. Typically used on Android. + * + * Requires {@link Caps#TextureCompressionETC1}. + */ + ETC1(4, false, true, false); private int bpp; private boolean isDepth; diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java index 3d0e580d0..2c53f2a37 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java @@ -356,6 +356,10 @@ public class LwjglRenderer implements Renderer { if (hasExtension("GL_EXT_texture_compression_latc")) { caps.add(Caps.TextureCompressionLATC); } + + if (hasExtension("GL_ARB_ES3_compatibility")) { + caps.add(Caps.TextureCompressionETC1); + } if (hasExtension("GL_EXT_packed_float") || caps.contains(Caps.OpenGL30)) { // This format is part of the OGL3 specification @@ -2208,6 +2212,9 @@ public class LwjglRenderer implements Renderer { throw new UnsupportedOperationException("Unknown buffer format."); } } else { + // Invalidate buffer data (orphan) before uploading new data. + + switch (vb.getFormat()) { case Byte: case UnsignedByte: diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java index 2eca2a06b..b9855a144 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java @@ -42,10 +42,10 @@ import java.util.EnumSet; import java.util.logging.Level; import java.util.logging.Logger; import static org.lwjgl.opengl.ARBDepthBufferFloat.*; +import org.lwjgl.opengl.ARBES3Compatibility; import static org.lwjgl.opengl.ARBHalfFloatPixel.*; import static org.lwjgl.opengl.ARBTextureFloat.*; import static org.lwjgl.opengl.ARBTextureMultisample.*; -import org.lwjgl.opengl.ContextCapabilities; import static org.lwjgl.opengl.EXTPackedDepthStencil.*; import static org.lwjgl.opengl.EXTPackedFloat.*; import static org.lwjgl.opengl.EXTTextureArray.*; @@ -142,6 +142,11 @@ class TextureUtil { // LTC/LATC/3Dc formats setFormat(Format.LTC, GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE, true); setFormat(Format.LATC, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, true); + + // ETC1 support on regular OpenGL requires ES3 compatibility extension. + // NOTE: ETC2 is backwards compatible with ETC1, so we can + // upload ETC1 textures as ETC2. + setFormat(Format.ETC1, ARBES3Compatibility.GL_COMPRESSED_RGB8_ETC2, GL_RGB, GL_UNSIGNED_BYTE, true); } //sRGB formats @@ -160,6 +165,11 @@ class TextureUtil { public static GLImageFormat getImageFormat(EnumSet caps, Format fmt, boolean isSrgb){ switch (fmt){ + case ETC1: + if (!caps.contains(Caps.TextureCompressionETC1)) { + return null; + } + break; case DXT1: case DXT1A: case DXT3: