diff --git a/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg b/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg index b350b696f6..7d339204ec 100644 --- a/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg +++ b/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg @@ -1,4 +1,3 @@ INCLUDE com/jme3/asset/General.cfg # Desktop-specific loaders -LOADER com.jme3.cursors.plugins.CursorLoader : ani, cur, ico diff --git a/jme3-core/src/plugins/java/com/jme3/cursors/plugins/CursorConverter.java b/jme3-core/src/plugins/java/com/jme3/cursors/plugins/CursorConverter.java new file mode 100644 index 0000000000..89bdaefa81 --- /dev/null +++ b/jme3-core/src/plugins/java/com/jme3/cursors/plugins/CursorConverter.java @@ -0,0 +1,75 @@ +package com.jme3.cursors.plugins; + +import java.nio.IntBuffer; + +import com.jme3.math.ColorRGBA; +import com.jme3.texture.Image; +import com.jme3.texture.Texture2D; +import com.jme3.texture.image.ImageRaster; +import com.jme3.util.BufferUtils; + +/** + * Convert any image like object to a {@link JmeCursor}. + */ +public class CursorConverter { + /** + * Convert a {@link Texture2D} to a {@link JmeCursor}. + * Doesn't support cursor animations. + * The coordinate system used is the same specified in {@link JmeCursor}. The start + * point is 0, 0 being lower left. + * + * @param cursorImage The texture to convert. No modification will be done to the object. + * + * @return The {@link JmeCursor} using a deep copy of {@link Texture2D.getImage}. + */ + public static JmeCursor fromTexture(Texture2D cursorImage) { + Image image = cursorImage.getImage().clone(); + + if (image == null) { + throw new NullPointerException("There is not an image set to the Texture2D"); + } + + int imageHeight = image.getHeight(); + int imageWidth = image.getWidth(); + + IntBuffer adaptedImageData = getDataAsIntBuffer(image); + + JmeCursor jmeCursor = new JmeCursor(); + jmeCursor.setWidth(imageWidth); + jmeCursor.setHeight(imageHeight); + jmeCursor.setxHotSpot(0); + jmeCursor.setyHotSpot(imageHeight); + jmeCursor.setNumImages(1); + jmeCursor.setImagesDelay(null); + jmeCursor.setImagesData(adaptedImageData); + return jmeCursor; + } + + private static IntBuffer getDataAsIntBuffer(Image image) { + int width = image.getWidth(); + int height = image.getHeight(); + + ImageRaster raster = ImageRaster.create(image); + + IntBuffer data = BufferUtils.createIntBuffer(width * height); + + //ARGB color system is needed to show cursors correctly. + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + ColorRGBA color = raster.getPixel(x, y); + + int a = (int) (color.a * 255) & 0xFF; + int r = (int) (color.r * 255) & 0xFF; + int g = (int) (color.g * 255) & 0xFF; + int b = (int) (color.b * 255) & 0xFF; + + int argb = (a << 24) | (r << 16) | (g << 8) | b; + + data.put(argb); + } + } + + data.flip(); + return data; + } +} \ No newline at end of file diff --git a/jme3-desktop/src/main/java/com/jme3/cursors/plugins/CursorLoader.java b/jme3-desktop/src/main/java/com/jme3/cursors/plugins/CursorLoader.java index 7d530ad960..101f4c5894 100644 --- a/jme3-desktop/src/main/java/com/jme3/cursors/plugins/CursorLoader.java +++ b/jme3-desktop/src/main/java/com/jme3/cursors/plugins/CursorLoader.java @@ -51,9 +51,16 @@ import javax.imageio.ImageIO; /** + * Supports loading of .ico, .ani, and .cur cursor file formats. + * * Created Jun 5, 2012 9:45:58 AM * @author MadJack + * + * @deprecated This class is not cross-platform, and the supported file formats are no longer commonly used. + * + * */ +@Deprecated public class CursorLoader implements AssetLoader { final private static int FDE_OFFSET = 6; // first directory entry offset diff --git a/jme3-examples/src/main/java/jme3test/gui/TestCursor.java b/jme3-examples/src/main/java/jme3test/gui/TestCursor.java index 3ba14216d7..812ab4e397 100644 --- a/jme3-examples/src/main/java/jme3test/gui/TestCursor.java +++ b/jme3-examples/src/main/java/jme3test/gui/TestCursor.java @@ -1,7 +1,12 @@ package jme3test.gui; import com.jme3.app.SimpleApplication; +import com.jme3.cursors.plugins.CursorConverter; import com.jme3.cursors.plugins.JmeCursor; +import com.jme3.texture.Image; +import com.jme3.texture.image.ImageRaster; +import com.jme3.texture.Texture2D; +import com.jme3.math.ColorRGBA; import java.util.ArrayList; /** @@ -48,15 +53,41 @@ public void simpleInitApp() { * * The animated cursor has been made by Pointer Adic and can be found here: * http://www.rw-designer.com/cursor-set/monkey + * + * At date of 2026/05/22, the three cursor examples has been converter to png formats. + * Checking and following the licences restrictions in the process. */ - cursors.add((JmeCursor) assetManager.loadAsset("Textures/Cursors/meme.cur")); - cursors.add((JmeCursor) assetManager.loadAsset("Textures/Cursors/nyancat.ico")); - cursors.add((JmeCursor) assetManager.loadAsset("Textures/Cursors/monkey.ani")); + + Image[] textureCursors = { + (Image) assetManager.loadAsset("Textures/Cursors/meme.png"), + (Image) assetManager.loadAsset("Textures/Cursors/nyancat.png"), + (Image) assetManager.loadAsset("Textures/Cursors/monkey.png") + }; + + for (Image cursor : textureCursors) { + flipVertically(cursor); + cursors.add(CursorConverter.fromTexture(new Texture2D(cursor))); + } sysTime = System.currentTimeMillis(); inputManager.setMouseCursor(cursors.get(count)); } + private void flipVertically(Image image) { + int height = image.getHeight(); + int width = image.getWidth(); + + ImageRaster raster = ImageRaster.create(image); + + for (int i = 0; i < width; i++) { + for (int j = 0; j < height / 2; j++){ + ColorRGBA reserve = raster.getPixel(i, j); + raster.setPixel(i, j, raster.getPixel(i, height - j -1)); + raster.setPixel(i, height - j -1, reserve); + } + } + } + @Override public void simpleUpdate(float tpf) { long currentTime = System.currentTimeMillis(); diff --git a/jme3-testdata/src/main/resources/Textures/Cursors/meme.cur b/jme3-testdata/src/main/resources/Textures/Cursors/meme.cur deleted file mode 100644 index 89c8a68e79..0000000000 Binary files a/jme3-testdata/src/main/resources/Textures/Cursors/meme.cur and /dev/null differ diff --git a/jme3-testdata/src/main/resources/Textures/Cursors/meme.png b/jme3-testdata/src/main/resources/Textures/Cursors/meme.png new file mode 100644 index 0000000000..4be43cc96b Binary files /dev/null and b/jme3-testdata/src/main/resources/Textures/Cursors/meme.png differ diff --git a/jme3-testdata/src/main/resources/Textures/Cursors/monkey.ani b/jme3-testdata/src/main/resources/Textures/Cursors/monkey.ani deleted file mode 100644 index 68b125ce21..0000000000 Binary files a/jme3-testdata/src/main/resources/Textures/Cursors/monkey.ani and /dev/null differ diff --git a/jme3-testdata/src/main/resources/Textures/Cursors/monkey.png b/jme3-testdata/src/main/resources/Textures/Cursors/monkey.png new file mode 100644 index 0000000000..fdb5a0e994 Binary files /dev/null and b/jme3-testdata/src/main/resources/Textures/Cursors/monkey.png differ diff --git a/jme3-testdata/src/main/resources/Textures/Cursors/nyancat.ico b/jme3-testdata/src/main/resources/Textures/Cursors/nyancat.ico deleted file mode 100644 index ab26e914cb..0000000000 Binary files a/jme3-testdata/src/main/resources/Textures/Cursors/nyancat.ico and /dev/null differ diff --git a/jme3-testdata/src/main/resources/Textures/Cursors/nyancat.png b/jme3-testdata/src/main/resources/Textures/Cursors/nyancat.png new file mode 100644 index 0000000000..36e9b33938 Binary files /dev/null and b/jme3-testdata/src/main/resources/Textures/Cursors/nyancat.png differ