Hi all,
when I try to create an animated mouse cursor with lwjgl Cursor I get the strangest results.
Here is the code I use:
private static Cursor getCursor() throws IOException, LWJGLException{
// set width, height and amount of cursors
int cursorWidth = 32;
int cursorHeight = 32;
int cursorAmount = 16;
// set local fields
/* cursor images get prestored here */
BufferedImage images = ImageIO.read(new File("data/img/input/mouseCursor.png"));
/* empty array needed for the images.getRGB method */
int[] rgbs = new int[cursorWidth*cursorHeight];
/* this contains the rgb information for every pixel in every cursor */
IntBuffer imageBuffer = IntBuffer.allocate(images.getWidth()*images.getHeight());
/* this should only need a size of 16 (cursorAmount), as delayBuffer should store the delay between 2 different cursors.
* however, if delayBuffer is smaller, the Cursor constructor throws the following error:
* java.lang.IllegalArgumentException: width*height*numImages > images.remaining()
*/
IntBuffer delayBuffer = IntBuffer.allocate(images.getWidth()*images.getHeight());
// put images into imageBuffer
for( int y = 0; y < images.getHeight()/cursorHeight; y++)
for (int x = 0; x < images.getWidth()/cursorWidth; x++)
if( y*(images.getWidth()/cursorWidth)+x < cursorAmount)
imageBuffer.put( images.getRGB(x*cursorWidth, y*cursorHeight, cursorWidth, cursorHeight, rgbs, 0, cursorWidth));
// put delay into delayBuffer
for(int i = 0; i < cursorAmount; i++)
delayBuffer.put(1000); // changing this value does nothing at all
// rewind buffers
imageBuffer.rewind();
delayBuffer.rewind();
// return new cursor
return new Cursor( cursorWidth,cursorHeight, // width and height of a single cursor image
0, cursorHeight-1, // relative hotspot of cursor
cursorAmount, // amounts of cursors (numImages)
imageBuffer, // imageBuffer containing the cursor images
delayBuffer); // delayBuffer containing the delays between 2 different images
/* note the following oddities:
* - when cursorAmount is 1 and delayBuffer null the cursor is displayed correctly
* - when imageBuffer and delayBuffer are swapped in the constructor (!), the different cursor images are displayed, but without delay between them. (changing the delay values doesn't do anything)
* - when delayBuffer is allocated with a size smaller then width*height it throws this error: java.lang.IllegalArgumentException: width*height*numImages > images.remaining()
*/
}
- This code is working as it should, only when I create a single image cursor (numImages = 1, delayBuffer = null).
- When I allocate the size for the delayBuffer with equivalent to the numImages (1 delayBuffer entry for each image, thats how it should be, right?), I get this error: "java.lang.IllegalArgumentException: width*height*numImages > images.remaining()". This is an error thrown by the Cursor constructor (see below), that should not be related to the delayBuffer Size at all!
- When I allocate the size for the delayBuffer equivalent to the allocated size for the imageBuffer, the code is compiling, but not drawing any cursor at all
- Here is the weirdest thing: When I switch delayBuffer with imageBuffer in the Constructor (meaning I give the imageBuffer I create to the Cursor Constructor as DelayBuffer and the delayBuffer as ImageBuffer), it is drawing all cursors from the imageBuffer, but without delay between them (they just flash). Nothing I do with the delayBuffer changes anything (I tried values from Integer.MIN_VALUE to Integer.MAX_VALUE, no difference at all, cursor images just flash through). To make it more clear, this happens, when I call the constructor like this:
new Cursor( cursorWidth,cursorHeight, // width and height of a single cursor image
0, cursorHeight-1, // relative hotspot of cursor
cursorAmount, // amounts of cursors (numImages)
delayBuffer, // imageBuffer containing the cursor images
imageBuffer); // delayBuffer containing the delays between 2 different images
Here is the Cursor Constructor source code
public Cursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException {
synchronized (OpenGLPackageAccess.global_lock) {
if ((getCapabilities() & CURSOR_ONE_BIT_TRANSPARENCY) == 0)
throw new LWJGLException("Native cursors not supported");
images = NondirectBufferWrapper.wrapBuffer(images, width*height*numImages);
if (delays != null)
delays = NondirectBufferWrapper.wrapBuffer(delays, numImages);
if (!Mouse.isCreated())
throw new IllegalStateException("Mouse must be created before creating cursor objects");
if (width*height*numImages > images.remaining())
throw new IllegalArgumentException("width*height*numImages > images.remaining()");
if (xHotspot >= width || xHotspot < 0)
throw new IllegalArgumentException("xHotspot > width || xHotspot < 0");
if (yHotspot >= height || yHotspot < 0)
throw new IllegalArgumentException("yHotspot > height || yHotspot < 0");
Sys.initialize();
// Hmm
yHotspot = height - 1 - yHotspot;
// create cursor (or cursors if multiple images supplied)
cursors = createCursors(width, height, xHotspot, yHotspot, numImages, images, delays);
}
}
Please have a look at this, I am really growing desperate here