Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ javadoc_deploy.pub
!.vscode/settings.json
!.vscode/JME_style.xml
!.vscode/extensions.json
joysticks-*.txt
hs_err_pid*.log
3 changes: 3 additions & 0 deletions common.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ repositories {
flatDir {
dirs rootProject.file('lib')
}
maven {
url "https://maven.rblb.it/riccardobl/angle-natives"
}
}

dependencies {
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ lwjgl3-opencl = { module = "org.lwjgl:lwjgl-opencl", version.ref = "lwjgl3"
lwjgl3-opengl = { module = "org.lwjgl:lwjgl-opengl", version.ref = "lwjgl3" }
lwjgl3-openvr = { module = "org.lwjgl:lwjgl-openvr", version.ref = "lwjgl3" }
lwjgl3-ovr = { module = "org.lwjgl:lwjgl-ovr", version.ref = "lwjgl3" }
lwjgl3-opengles = { module = "org.lwjgl:lwjgl-opengles", version.ref = "lwjgl3" }

mokito-core = "org.mockito:mockito-core:3.12.4"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,16 +348,16 @@ public String glGetProgramInfoLog(int program, int maxLength) {

@Override
public long glGetQueryObjectui64(int query, int pname) {
IntBuffer buff = IntBuffer.allocate(1);
IntBuffer buff = tmpBuff.clear();
//FIXME This is wrong IMO should be glGetQueryObjectui64v with a LongBuffer but it seems the API doesn't provide it.
GLES30.glGetQueryObjectuiv(query, pname, buff);
return buff.get(0);
}

@Override
public int glGetQueryObjectiv(int query, int pname) {
IntBuffer buff = IntBuffer.allocate(1);
GLES30.glGetQueryiv(query, pname, buff);
IntBuffer buff = tmpBuff.clear();
GLES30.glGetQueryObjectuiv(query, pname, buff);
return buff.get(0);
}

Expand Down Expand Up @@ -758,5 +758,10 @@ public void glGenVertexArrays(IntBuffer arrays) {

}

@Override
public String glGetString(int name, int index) {
return GLES30.glGetStringi(name, index);
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ public interface GLES_30 extends GL {

public static final int GL_RGB10_A2 = 0x8059;
public static final int GL_UNSIGNED_INT_2_10_10_10_REV = 0x8368;

public static final int GL_NUM_EXTENSIONS = 0x821D;

public void glBindVertexArray(int array);

public void glDeleteVertexArrays(IntBuffer arrays);

public void glGenVertexArrays(IntBuffer arrays);

public String glGetString(final int name, final int index);

}
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,15 @@ private HashSet<String> loadExtensions() {
gl3.glGetInteger(GL3.GL_NUM_EXTENSIONS, intBuf16);
int extensionCount = intBuf16.get(0);
for (int i = 0; i < extensionCount; i++) {
String extension = gl3.glGetString(GL.GL_EXTENSIONS, i);
String extension = gl3.glGetString(GL3.GL_EXTENSIONS, i);
extensionSet.add(extension);
}
} else if (caps.contains(Caps.OpenGLES30)) {
GLES_30 gles = (GLES_30) gl;
gles.glGetInteger(GLES_30.GL_NUM_EXTENSIONS, intBuf16);
int extensionCount = intBuf16.get(0);
for (int i = 0; i < extensionCount; i++) {
String extension = gles.glGetString(GLES_30.GL_EXTENSIONS, i);
extensionSet.add(extension);
}
} else {
Expand Down
4 changes: 3 additions & 1 deletion jme3-core/src/main/java/com/jme3/system/AppSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ public final class AppSettings extends HashMap<String, Object> {
*/
public static final String LWJGL_OPENAL = "LWJGL";

public static final String ANGLE_GLES3 = "ANGLE_GLES3";

/**
* Use the Android MediaPlayer / SoundPool based renderer for Android audio capabilities.
* <p>
Expand Down Expand Up @@ -282,7 +284,7 @@ public final class AppSettings extends HashMap<String, Object> {
defaults.put("Samples", 0);
defaults.put("Fullscreen", false);
defaults.put("Title", JmeVersion.FULL_NAME);
defaults.put("Renderer", LWJGL_OPENGL32);
defaults.put("Renderer", ANGLE_GLES3);
defaults.put("AudioRenderer", LWJGL_OPENAL);
defaults.put("DisableJoysticks", true);
defaults.put("UseInput", true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ public final class TGALoader implements AssetLoader {
// 11 - run-length encoded, black and white image
public static final int TYPE_BLACKANDWHITE_RLE = 11;

private static void convertBGRtoRGB(byte[] data, int dl){
for (int i = 0; i < data.length; i += dl) {
byte tmp = data[i];
data[i] = data[i + 2];
data[i + 2] = tmp;
}
}

@Override
public Object load(AssetInfo info) throws IOException {
if (!(info.getKey() instanceof TextureKey)) {
Expand Down Expand Up @@ -261,7 +269,8 @@ public static Image load(InputStream in, boolean flip) throws IOException {
// rawData[rawDataIndex++] = blue;
// }
}
format = Format.BGR8;
convertBGRtoRGB(rawData, dl);
format = Format.RGB8;
} else if (pixelDepth == 32) {
for (int i = 0; i <= (height - 1); i++) {
if (!flip) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public JmeContext newContext(AppSettings settings, Type contextType) {
|| contextType == JmeContext.Type.Headless) {
ctx = new NullContext();
ctx.setSettings(settings);
} else if (settings.getRenderer().startsWith("LWJGL")) {
} else if (settings.getRenderer().startsWith("LWJGL") || settings.getRenderer().startsWith("ANGLE")) {
ctx = newContextLwjgl(settings, contextType);
ctx.setSettings(settings);
} else if (settings.getRenderer().startsWith("JOGL")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme3.system.NativeLibraries.LibraryInfo;
import com.jme3.util.res.Resources;

/**
Expand Down Expand Up @@ -94,6 +95,16 @@ public static void registerNativeLibrary(NativeLibrary library) {
nativeLibraryMap.put(library.getKey(), library);
}

/**
* Register a new native library.
*
* This simply registers a known library, the actual extraction and loading is performed by calling
* {@link #loadNativeLibrary(java.lang.String, boolean) }.
*/
public static void registerNativeLibrary(LibraryInfo library) {
library.getNativeVariants().forEach(NativeLibraryLoader::registerNativeLibrary);
}

/**
* Register a new native library.
*
Expand Down Expand Up @@ -428,11 +439,15 @@ public static void extractNativeLibrary(Platform platform, String name, File tar
/**
* First extracts the native library and then loads it.
*
* @param name The name of the library to load.
* @param isRequired If true and the library fails to load, throw exception. If
* false, do nothing if it fails to load.
* @param name
* The name of the library to load.
* @param isRequired
* If true and the library fails to load, throw exception. If false, do nothing if it fails to
* load.
*
* @return The absolute path of the loaded library.
*/
public static void loadNativeLibrary(String name, boolean isRequired) {
public static String loadNativeLibrary(String name, boolean isRequired) {
if (JmeSystem.isLowPermissions()) {
throw new UnsupportedOperationException("JVM is running under "
+ "reduced permissions. Cannot load native libraries.");
Expand All @@ -453,15 +468,15 @@ public static void loadNativeLibrary(String name, boolean isRequired) {
" is not available for your OS: {1}",
new Object[]{name, platform});
}
return;
return null;
}
}

final String pathInJar = library.getPathInNativesJar();

if (pathInJar == null) {
// This platform does not require the native library to be loaded.
return;
return null;
}

URL url = Resources.getResource(pathInJar);
Expand All @@ -476,7 +491,7 @@ public static void loadNativeLibrary(String name, boolean isRequired) {
" was not found in the classpath via ''{1}''.",
new Object[]{library.getName(), pathInJar});
}
return;
return null;
}

// The library has been found and is ready to be extracted.
Expand Down Expand Up @@ -526,6 +541,8 @@ public static void loadNativeLibrary(String name, boolean isRequired) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "Loaded native library {0}.", library.getName());
}

return targetFile.getAbsolutePath();
} catch (IOException ex) {
/*if (ex.getMessage().contains("used by another process")) {
return;
Expand Down
29 changes: 27 additions & 2 deletions jme3-desktop/src/main/java/com/jme3/texture/plugins/AWTLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,27 @@ private void flipImage(short[] img, int width, int height, int bpp){
}
}

private static void convertBGRtoRGB(byte[] data){
for (int i = 0; i < data.length; i += 3) {
byte tmp = data[i];
data[i] = data[i + 2];
data[i + 2] = tmp;
}
}

private static void convertABGRtoRGBA(byte[] data){
for (int i = 0; i < data.length; i += 4) {
byte a = data[i];
byte b = data[i + 1];
byte g = data[i + 2];
byte r = data[i + 3];
data[i] = r;
data[i + 1] = g;
data[i + 2] = b;
data[i + 3] = a;
}
}

public Image load(BufferedImage img, boolean flipY){
int width = img.getWidth();
int height = img.getHeight();
Expand All @@ -110,18 +131,22 @@ public Image load(BufferedImage img, boolean flipY){
byte[] dataBuf1 = (byte[]) extractImageData(img);
if (flipY)
flipImage(dataBuf1, width, height, 32);

convertABGRtoRGBA(dataBuf1);

ByteBuffer data1 = BufferUtils.createByteBuffer(img.getWidth()*img.getHeight()*4);
data1.put(dataBuf1);
return new Image(Format.ABGR8, width, height, data1, null, com.jme3.texture.image.ColorSpace.sRGB);
return new Image(Format.RGBA8, width, height, data1, null, com.jme3.texture.image.ColorSpace.sRGB);
case BufferedImage.TYPE_3BYTE_BGR: // most common in JPEG images
byte[] dataBuf2 = (byte[]) extractImageData(img);
if (flipY)
flipImage(dataBuf2, width, height, 24);

convertBGRtoRGB(dataBuf2);

ByteBuffer data2 = BufferUtils.createByteBuffer(img.getWidth()*img.getHeight()*3);
data2.put(dataBuf2);
return new Image(Format.BGR8, width, height, data2, null, com.jme3.texture.image.ColorSpace.sRGB);
return new Image(Format.RGB8, width, height, data2, null, com.jme3.texture.image.ColorSpace.sRGB);
case BufferedImage.TYPE_BYTE_GRAY: // grayscale fonts
byte[] dataBuf3 = (byte[]) extractImageData(img);
if (flipY)
Expand Down
12 changes: 12 additions & 0 deletions jme3-desktop/src/main/java/jme3tools/converters/ImageToAwt.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,16 @@ public DecodeParams(int bpp, int rm, int rs, int im, int is){
private ImageToAwt() {
}

private static Format toGLESFormat(Format format){
if (format == Format.BGR8) {
return Format.RGB8;
}
if (format == Format.BGRA8 || format == Format.ABGR8 || format == Format.ARGB8) {
return Format.RGBA8;
}
return format;
}

private static int Ix(int x, int y, int w){
return y * w + x;
}
Expand Down Expand Up @@ -214,6 +224,8 @@ private static void writePixel(ByteBuffer buf, int idx, int pixel, int bpp){
* @param buf the output buffer (not null, modified)
*/
public static void convert(BufferedImage image, Format format, ByteBuffer buf) {
format = toGLESFormat(format);

DecodeParams p = params.get(format);
if (p == null)
throw new UnsupportedOperationException("Image format " + format + " is not supported");
Expand Down
4 changes: 2 additions & 2 deletions jme3-examples/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ dependencies {
implementation project(':jme3-effects')
implementation project(':jme3-jbullet')
implementation project(':jme3-jogg')
implementation project(':jme3-lwjgl')
// implementation project(':jme3-lwjgl3')
// implementation project(':jme3-lwjgl')
implementation project(':jme3-lwjgl3')
implementation project(':jme3-networking')
implementation project(':jme3-niftygui')
implementation project(':jme3-plugins')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.jme3.math.FastMath;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.system.AppSettings;
import com.jme3.util.SkyFactory;
import com.jme3.util.mikktspace.MikktspaceTangentGenerator;

Expand All @@ -49,7 +50,13 @@ public class TestPBRSimple extends SimpleApplication {
private boolean REALTIME_BAKING = false;

public static void main(String[] args) {
new TestPBRSimple().start();
AppSettings settings = new AppSettings(true);
settings.setX11PlatformPreferred(true);
settings.setRenderer(AppSettings.ANGLE_GLES3);
settings.setGammaCorrection(true);
TestPBRSimple app = new TestPBRSimple();
app.setSettings(settings);
app.start();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Sphere;
import com.jme3.system.AppSettings;
import com.jme3.util.mikktspace.MikktspaceTangentGenerator;

public class TestUnshadedModel extends SimpleApplication {

public static void main(String[] args){
AppSettings settings = new AppSettings(true);
settings.setX11PlatformPreferred(true);
settings.setRenderer(AppSettings.ANGLE_GLES3);
TestUnshadedModel app = new TestUnshadedModel();
app.setSettings(settings);
app.start();
}

Expand Down
4 changes: 4 additions & 0 deletions jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java
Original file line number Diff line number Diff line change
Expand Up @@ -809,5 +809,9 @@ public void glGenVertexArrays(IntBuffer arrays) {
throw new UnsupportedOperationException("Unimplemented method 'glGenVertexArrays'");
}

@Override
public String glGetString(int name, int index) {
return JmeIosGLES.glGetStringi(name, index);
}

}
2 changes: 2 additions & 0 deletions jme3-ios/src/main/java/com/jme3/renderer/ios/JmeIosGLES.java
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ private JmeIosGLES() {
public static native String glGetShaderInfoLog(int shader);
public static native void glGetShaderiv(int shader, int pname, int[] params, int offset);
public static native String glGetString(int name);

public static native String glGetStringi(int name, int index);
public static native int glGetUniformLocation(int program, String name);
public static native boolean glIsEnabled(int cap);
public static native boolean glIsFramebuffer(int framebuffer);
Expand Down
13 changes: 13 additions & 0 deletions jme3-lwjgl3/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ dependencies {
api libs.lwjgl3.opencl
api libs.lwjgl3.opengl

api libs.lwjgl3.opengles
api("io.github.riccardobl:angle-natives:2026-01-24-2")

runtimeOnly("io.github.riccardobl:angle-natives:2026-01-24-2")
runtimeOnly(variantOf(libs.lwjgl3.base){ classifier('natives-windows') })
runtimeOnly(variantOf(libs.lwjgl3.base){ classifier('natives-windows-x86') })
runtimeOnly(variantOf(libs.lwjgl3.base){ classifier('natives-linux') })
Expand Down Expand Up @@ -52,6 +56,15 @@ dependencies {
runtimeOnly(variantOf(libs.lwjgl3.openal){ classifier('natives-linux-arm64') })
runtimeOnly(variantOf(libs.lwjgl3.openal){ classifier('natives-macos') })
runtimeOnly(variantOf(libs.lwjgl3.openal){ classifier('natives-macos-arm64') })


runtimeOnly(variantOf(libs.lwjgl3.opengles){ classifier('natives-windows') })
runtimeOnly(variantOf(libs.lwjgl3.opengles){ classifier('natives-windows-x86') })
runtimeOnly(variantOf(libs.lwjgl3.opengles){ classifier('natives-linux') })
runtimeOnly(variantOf(libs.lwjgl3.opengles){ classifier('natives-linux-arm32') })
runtimeOnly(variantOf(libs.lwjgl3.opengles){ classifier('natives-linux-arm64') })
runtimeOnly(variantOf(libs.lwjgl3.opengles){ classifier('natives-macos') })
runtimeOnly(variantOf(libs.lwjgl3.opengles){ classifier('natives-macos-arm64') })
}

javadoc {
Expand Down
Loading
Loading