You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PImage.getNative() always returns null since 4.0a3 (commit: e46ecea).
This produces a NullPointerException if PApplet.cursor(PImage img) or PApplet.cursor(PImage img, int x, int y) is invoked while the renderer is set to JAVA2D/P2D/P3D.
The recently adopted null value return as opposed to an java.awt.Image seems to stem from contributors practicing exorcism to evict the evil AWT (a billion thanks for making Processing available and updated, by the way).
I think I've found a decent way to keep the cursor(PImage) functionality for the JOGL renderers (P2D/P3D), while at the same time getting rid of the two awt.image dependencies in PSurfaceJOGL.
Sidenote # 1 (JavaFX problems):
For FX2D the behaviour is almost as expected, but also have some problems:
The custom cursor remains after mouse leaving the sketch window (might be intentional?).
The custom cursor disappears when switching to another application (good) but doesn't reappear when switching back to the sketch (bad). However, this seems to be unrelated to the issues with other renderers and is not discussed more in this submission.
Sidenote # 2 (quick fix for AWT/JOGL):
As a temporary quick-fix – for those in desperate need of cursor functionality – using PImageAWT (as proposed in the wiki) works fine as far as I can tell.
For example, the following code will result in the expecting behaviour (a square little cursor):
The mouse cursor should change to the specified PImage when invoking cursor(PImage someImage).
Current Behavior
A NullPointerException is always thrown for P2D/P3D/JAVA2D renderers.
Steps to Reproduce
Run the following code:
size(100, 100, P2D); // i.e. getSurface() will return a PSurfaceJOGL.PImage cursor =createImage(16, 16, ARGB); // an empty, transparent PImage.cursor(cursor); // should produce an empty (invisible) cursor.
A NullPointerException is thrown, if the specified renderer is P2D, P3D, JAVA2D or unspecified (= JAVA2D).
Your Environment
Processing version: 4.0a3
Operating System and OS version: MacOS Catalina 10.15.7
Possible Causes / Solutions
Cause:
The problem boils down to getNative() of PImage.java always returning null:
publicObjectgetNative() { // ignorereturnnull;
}
Backtrack:
In PApplet.java (4.0a3) cursor(PImage img) forwards to setCursor(PImage img, int x, int y) of the current surface, i.e. either PSurfaceAWT or PSurfaceJOGL for default JAVA2D or P2D/P3D renderers, respectively:
publicvoidsetCursor(PImageimage, inthotspotX, inthotspotY) {
Display disp = window.getScreen().getDisplay();
BufferedImage bimg = (BufferedImage)image.getNative(); // <<<<<<< Bad boy getNative() <<<<<<<// ...
Solution for PSurfaceJOGL:
For setCursor(PImage image, int hotspotX, int hotspotY) in PSurfaceJOGL, the dependency on AWT's BufferedImage seems redundant, but I may have misunderstood something. Also, I think it's unnessecary to declare a new disp variable since this should refer to the class variable display?
The code as of now, with my comments:
publicvoidsetCursor(PImageimage, inthotspotX, inthotspotY) {
Display disp = window.getScreen().getDisplay(); //<< Should be same as display variable of the class?BufferedImage bimg = (BufferedImage)image.getNative(); //<< REDUNDANT ???DataBufferInt dbuf = (DataBufferInt)bimg.getData().getDataBuffer(); //<< REDUNDANT ???int[] ipix = dbuf.getData(); //<< Should be exactly equal to image.pixels ?ByteBufferpixels=ByteBuffer.allocate(ipix.length *4);
pixels.asIntBuffer().put(ipix);
PixelFormat format =PixelFormat.ARGB8888;
finalDimension size =newDimension(bimg.getWidth(), bimg.getHeight());
PixelRectangle pixelrect =newPixelRectangle.GenericPixelRect(format, size, 0, false, pixels);
finalPointerIcon pi = disp.createPointerIcon(pixelrect, hotspotX, hotspotY);
display.getEDTUtil().invoke(false, newRunnable() {
@Overridepublicvoidrun() {
window.setPointerVisible(true);
window.setPointerIcon(pi);
}
});
}
As I understand it, the PImage.pixels array (int[]) already stores each pixel as a 32bit unsigned integer as specified by the already implemented PixelFormat.ARGB8888 (i.e.#AARRGGBB in hex notation). As such, casting from PImage -> Buffered Image -> DataBufferInt -> int[] should be redundant as we simply can use the PImage.pixels int array as it is.
If we also make use of loadPixels(), we make sure pixels is up to date (for example, I noticed pixels otherwise returned null for a newly created PGraphics).
Thanks for looking into it. For at least the next alpha (but probably the 4.0 release as well), I've decided to go a less ambitious direction with the AWT changes for better backwards compatibility.
This issue has been automatically locked. To avoid confusion with reports that have already been resolved, closed issues are automatically locked 30 days after the last comment. Please open a new issue for related bugs.
Created by: neonfabrik
Description
PImage.getNative()
always returnsnull
since 4.0a3 (commit: e46ecea).This produces a
NullPointerException
ifPApplet.cursor(PImage img)
orPApplet.cursor(PImage img, int x, int y)
is invoked while the renderer is set to JAVA2D/P2D/P3D.The recently adopted
null
value return as opposed to an java.awt.Image seems to stem from contributors practicing exorcism to evict the evil AWT (a billion thanks for making Processing available and updated, by the way).I think I've found a decent way to keep the cursor(PImage) functionality for the JOGL renderers (P2D/P3D), while at the same time getting rid of the two awt.image dependencies in PSurfaceJOGL.
Sidenote # 1 (JavaFX problems):
For FX2D the behaviour is almost as expected, but also have some problems:
However, this seems to be unrelated to the issues with other renderers and is not discussed more in this submission.
Sidenote # 2 (quick fix for AWT/JOGL):
As a temporary quick-fix – for those in desperate need of cursor functionality – using
PImageAWT
(as proposed in the wiki) works fine as far as I can tell.For example, the following code will result in the expecting behaviour (a square little cursor):
Expected Behavior
The mouse cursor should change to the specified PImage when invoking cursor(PImage someImage).
Current Behavior
A NullPointerException is always thrown for P2D/P3D/JAVA2D renderers.
Steps to Reproduce
NullPointerException
is thrown, if the specified renderer isP2D
,P3D
,JAVA2D
or unspecified (=JAVA2D
).Your Environment
Possible Causes / Solutions
Cause:
The problem boils down to getNative() of PImage.java always returning null:
Backtrack:
In PApplet.java (4.0a3)
cursor(PImage img)
forwards tosetCursor(PImage img, int x, int y)
of the current surface, i.e. either PSurfaceAWT or PSurfaceJOGL for default JAVA2D or P2D/P3D renderers, respectively:In PSurfaceAWT.java (4.0a3) we have ...
and in PSurfaceJOGL.java ...
Solution for PSurfaceJOGL:
For
setCursor(PImage image, int hotspotX, int hotspotY)
in PSurfaceJOGL, the dependency on AWT'sBufferedImage
seems redundant, but I may have misunderstood something. Also, I think it's unnessecary to declare a newdisp
variable since this should refer to the class variabledisplay
?The code as of now, with my comments:
As I understand it, the
PImage.pixels
array (int[]
) already stores each pixel as a 32bit unsigned integer as specified by the already implementedPixelFormat.ARGB8888
(i.e. #AARRGGBB in hex notation). As such, casting from PImage -> Buffered Image -> DataBufferInt -> int[] should be redundant as we simply can use thePImage.pixels
int array as it is.If we also make use of
loadPixels()
, we make surepixels
is up to date (for example, I noticedpixels
otherwise returned null for a newly created PGraphics).Proposed change (in PSurfaceJOGL.java):
The two
awt.image
dependencies can then also be removed:Proof of concept:
I have tested the following code in a processing sketch and it works as expected for P2D & P3D (& OPENGL).
The text was updated successfully, but these errors were encountered: