creating cursor from png

Started by APXEOLOG, April 13, 2011, 07:49:15

Previous topic - Next topic

APXEOLOG

Hi! I'm trying to create cursor from png failed... My code:
private int translate(byte b) {
		if (b < 0) {
			return 256 + b;
		}
		
		return b;
	}
	
	// texData format: RGBA, image in left top corner of texture
	private IntBuffer formBuffer(Texture tex) {
		byte[] pixelData = tex.getTextureData();
		
		IntBuffer ib = IntBuffer.allocate(tex.getImageWidth() * tex.getImageHeight() * 4);
		
		for (int x = 0; x < tex.getImageWidth(); x++)
			for (int y = 0; y < tex.getImageHeight(); y++) {
				int offset = x + (y * tex.getTextureWidth()) * 4;
				ib.put(translate(pixelData[offset + 3]));	// A
				ib.put(translate(pixelData[offset]));		// R
				ib.put(translate(pixelData[offset + 1]));	// G
				ib.put(translate(pixelData[offset + 2]));	// B
					
			}
		return ib;
	}
	
	public void ChangeCursor(String name) {
		Texture newCursor = Resource.cursors.get(name);
		try {
			IntBuffer ib = formBuffer(newCursor);
			org.lwjgl.input.Cursor c = new org.lwjgl.input.Cursor(
					newCursor.getImageWidth(),
					newCursor.getImageHeight(),
					0,
					0,
					1,
					ib,
					null);
			org.lwjgl.input.Mouse.setNativeCursor(c);
		} catch (LWJGLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//org.lwjgl.input.Mouse.setNativeCursor(arg0)
	}


my image is 22*22, and i have error:
Exception in thread "main" java.lang.IllegalArgumentException: Number of remaini
ng buffer elements is 0, must be at least 484
        at org.lwjgl.BufferChecks.throwBufferSizeException(BufferChecks.java:162
)
        at org.lwjgl.BufferChecks.checkBufferSize(BufferChecks.java:189)
        at org.lwjgl.NondirectBufferWrapper.wrapBuffer(NondirectBufferWrapper.ja
va:111)
        at org.lwjgl.input.Cursor.<init>(Cursor.java:89)


Any ideas?

CodeBunny

You might find it easier to use the Java ImageIO functions - it'll auto-load your image, and you can access the data much more easily.

Basically, load a BufferedImage, and then get its data.

jediTofu

When you put something in a buffer, it moves the position of where to read, so the marker is at the end.
Just do this:

IntBuffer ib = formBuffer(newCursor);
ib.rewind();
org.lwjgl.input.Cursor c = new org.lwjgl.input.Cursor(...

Also, 22x22 probably won't work.  It needs to be at least the minimum size and not exceed the maximum size on the system (check javadoc on input); also it probably needs to be a power of 2 if want it to work for all systems.
cool story, bro

Matthias

You can also take a look at TWL - it uses the TWL PNGDecoder and then creates a LWJGL native cursor from a part of it with it's LWJGLCursor class.

Simon Felix

This code sets up a 16x16 PNG as IntBuffer for use as cursor:

  public static IntBuffer getHandMousePointer()
  {
    Image c=Toolkit.getDefaultToolkit().getImage(Icon.class.getResource("/data/cursor_hand.png"));
    BufferedImage biCursor=new BufferedImage(16,16,BufferedImage.TYPE_INT_ARGB);
    while(!biCursor.createGraphics().drawImage(c,0,15,15,0,0,0,15,15,null))
      try
      {
        Thread.sleep(5);
      }
      catch(InterruptedException e)
      {
      }
    
    int[] data=biCursor.getRaster().getPixels(0,0,16,16,(int[])null);
    
    IntBuffer ib=BufferUtils.createIntBuffer(16*16);
    for(int i=0;i<data.length;i+=4)
      ib.put(data[i] | data[i+1]<<8 | data[i+2]<<16 | data[i+3]<<24);
    ib.flip();
    return ib;
  }
Download Cultris II, the fastest Tetris clone from http://gewaltig.net/