Skip to content
Open
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
1 change: 0 additions & 1 deletion jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
INCLUDE com/jme3/asset/General.cfg

# Desktop-specific loaders
LOADER com.jme3.cursors.plugins.CursorLoader : ani, cur, ico
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
37 changes: 34 additions & 3 deletions jme3-examples/src/main/java/jme3test/gui/TestCursor.java
Original file line number Diff line number Diff line change
@@ -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;

/**
Expand Down Expand Up @@ -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();
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading