diff --git a/.gitignore b/.gitignore
index 95436daf3..a18de53e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,11 @@
.DS_Store
.AppleDouble
-*.iml
._*
*~
/build/shared/reference.zip
*.x
-# temporary, until we complete the move to IntelliJ
#*.iml
#/.idea
diff --git a/app/processing4-app.iml b/app/processing4-app.iml
new file mode 100644
index 000000000..b0634b773
--- /dev/null
+++ b/app/processing4-app.iml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/macosx/appbundler/processing4-appbundler.iml b/build/macosx/appbundler/processing4-appbundler.iml
new file mode 100644
index 000000000..c30dab7bf
--- /dev/null
+++ b/build/macosx/appbundler/processing4-appbundler.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/shared/tools/MovieMaker/processing4-tools-moviemaker.iml b/build/shared/tools/MovieMaker/processing4-tools-moviemaker.iml
new file mode 100644
index 000000000..608b28585
--- /dev/null
+++ b/build/shared/tools/MovieMaker/processing4-tools-moviemaker.iml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/shared/tools/ThemeEngine/processing4-tools-theme.iml b/build/shared/tools/ThemeEngine/processing4-tools-theme.iml
new file mode 100644
index 000000000..2d35c6077
--- /dev/null
+++ b/build/shared/tools/ThemeEngine/processing4-tools-theme.iml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/.gitignore b/core/.gitignore
index 541feadb3..d2cc0abf0 100644
--- a/core/.gitignore
+++ b/core/.gitignore
@@ -1,6 +1,5 @@
bin
bin-test
-.idea
/library/gluegen-rt*.jar
/library/jogl-all*.jar
diff --git a/core/.idea/.gitignore b/core/.idea/.gitignore
new file mode 100644
index 000000000..26d33521a
--- /dev/null
+++ b/core/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/core/.idea/ant.xml b/core/.idea/ant.xml
new file mode 100644
index 000000000..a2a476982
--- /dev/null
+++ b/core/.idea/ant.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/.idea/misc.xml b/core/.idea/misc.xml
new file mode 100644
index 000000000..1763e153b
--- /dev/null
+++ b/core/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/.idea/modules.xml b/core/.idea/modules.xml
new file mode 100644
index 000000000..d5b4e612a
--- /dev/null
+++ b/core/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/.idea/vcs.xml b/core/.idea/vcs.xml
new file mode 100644
index 000000000..6c0b86358
--- /dev/null
+++ b/core/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/methods/processing4-core-preproc.iml b/core/methods/processing4-core-preproc.iml
new file mode 100644
index 000000000..bea76e7d8
--- /dev/null
+++ b/core/methods/processing4-core-preproc.iml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/processing4-core.iml b/core/processing4-core.iml
new file mode 100644
index 000000000..129c87525
--- /dev/null
+++ b/core/processing4-core.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/src/processing/core/PShape.java b/core/src/processing/core/PShape.java
index 95136e9a7..0cf0adfc3 100644
--- a/core/src/processing/core/PShape.java
+++ b/core/src/processing/core/PShape.java
@@ -3024,9 +3024,11 @@ public class PShape implements PConstants {
/**
* Return true if this x, y coordinate is part of this shape. Only works
* with PATH shapes or GROUP shapes that contain other GROUPs or PATHs.
+ * This method is not imperfect and doesn't account for all cases
+ * (not all complex shapes: concave shapes or holes may have issues).
*/
public boolean contains(float x, float y) {
- if (family == PATH) {
+ if (family == PATH || family == GEOMETRY) {
PVector p = new PVector(x, y);
if (matrix != null) {
// apply the inverse transformation matrix to the point coordinates
diff --git a/core/src/processing/opengl/PJOGL.java b/core/src/processing/opengl/PJOGL.java
index c138bddd5..cfe58dc9f 100644
--- a/core/src/processing/opengl/PJOGL.java
+++ b/core/src/processing/opengl/PJOGL.java
@@ -51,6 +51,7 @@ import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLDrawable;
import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
+import com.jogamp.opengl.GLRendererQuirks;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.glu.GLUtessellator;
import com.jogamp.opengl.glu.GLUtessellatorCallbackAdapter;
@@ -128,6 +129,8 @@ public class PJOGL extends PGL {
}
+ private static boolean forceSharedObjectSync = true;
+
///////////////////////////////////////////////////////////////
// Initialization, finalization
@@ -183,6 +186,11 @@ public class PJOGL extends PGL {
}
+ public boolean needSharedObjectSync() {
+ return forceSharedObjectSync || gl.getContext().hasRendererQuirk(GLRendererQuirks.NeedSharedObjectSync);
+ }
+
+
public void setFps(float fps) {
if (!setFps || targetFps != fps) {
if (60 < fps) {
diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java
index 8f36aa592..2113b5299 100644
--- a/core/src/processing/opengl/PShapeOpenGL.java
+++ b/core/src/processing/opengl/PShapeOpenGL.java
@@ -3447,12 +3447,16 @@ public class PShapeOpenGL extends PShape {
//
- // Geometry utils
-
- // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
+ /**
+ * Return true if this x, y coordinate is part of this shape. Only works
+ * with PATH shapes or GROUP shapes that contain other GROUPs or PATHs.
+ * This method is not imperfect and doesn't account for all cases
+ * (not all complex shapes: concave shapes or holes may have issues).
+ */
@Override
public boolean contains(float x, float y) {
- if (family == PATH) {
+ if (family == PATH || family == GEOMETRY) {
+ // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
boolean c = false;
for (int i = 0, j = inGeo.vertexCount-1; i < inGeo.vertexCount; j = i++) {
if (((inGeo.vertices[3 * i + 1] > y) != (inGeo.vertices[3 * j + 1] > y)) &&
diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java
index 4b4910011..b35a8a9b4 100644
--- a/core/src/processing/opengl/PSurfaceJOGL.java
+++ b/core/src/processing/opengl/PSurfaceJOGL.java
@@ -39,6 +39,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -56,6 +57,7 @@ import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.GLDrawableFactory;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.nativewindow.WindowClosingProtocol;
import com.jogamp.newt.Display;
@@ -107,6 +109,11 @@ public class PSurfaceJOGL implements PSurface {
protected NewtCanvasAWT canvas;
+ protected static GLAutoDrawable sharedDrawable;
+ protected static ArrayList animators = new ArrayList<>();
+ private final static Object sharedSyncMutex = new Object();
+ private Object syncMutex;
+
protected int windowScaleFactor;
protected float[] currentPixelScale = { 0, 0 };
@@ -254,6 +261,29 @@ public class PSurfaceJOGL implements PSurface {
caps.setBackgroundOpaque(true);
caps.setOnscreen(true);
pgl.setCaps(caps);
+
+ if (sharedDrawable == null) {
+ // Create a shared drawable to enable context sharing across multiple GL windows
+ // https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GLSharedContextSetter.html
+ sharedDrawable = GLDrawableFactory.getFactory(profile).createDummyAutoDrawable(null, true, caps, null);
+ sharedDrawable.display();
+ }
+ }
+
+
+ // To properly deal with synchronization when context sharing across multiple drawables (windows), we need a
+ // synchronization mutex object to ensure that rendering of each frame completes in their respective animator thread:
+ // https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GLSharedContextSetter.html#synchronization
+ private Object getSyncMutex(GLAutoDrawable drawable) {
+ pgl.getGL(drawable);
+ if (pgl.needSharedObjectSync()) {
+ syncMutex = sharedSyncMutex;
+ } else {
+ if (syncMutex == null) {
+ syncMutex = new Object();
+ }
+ }
+ return syncMutex;
}
@@ -327,6 +357,8 @@ public class PSurfaceJOGL implements PSurface {
window.setTopLevelSize((int) displayRect.getWidth(), (int) displayRect.getHeight());
}
}
+
+ window.setSharedAutoDrawable(sharedDrawable);
}
@@ -354,6 +386,7 @@ public class PSurfaceJOGL implements PSurface {
}
animator = new FPSAnimator(window, 60);
+ animators.add(animator);
drawException = null;
animator.setUncaughtExceptionHandler((animator, drawable, cause) -> {
@@ -637,6 +670,10 @@ public class PSurfaceJOGL implements PSurface {
drawExceptionHandler = null;
}
if (animator != null) {
+ // Stops all other animators to avoid exceptions when closing a window in a multiple window configuration
+ for (FPSAnimator ani: animators) {
+ if (ani != animator) ani.stop();
+ }
return animator.stop();
} else {
return false;
@@ -753,9 +790,13 @@ public class PSurfaceJOGL implements PSurface {
public class DrawListener implements GLEventListener {
+ private boolean isInit = false;
+
public void display(GLAutoDrawable drawable) {
+ if (!isInit) return;
+
if (display.getEDTUtil().isCurrentThreadEDT()) {
- // For an unknown reason, the first two frames of the animator run on
+ // For some unknown reason, a few frames of the animator run on
// the EDT. For those, we just skip this draw call to avoid badness.
return;
}
@@ -770,17 +811,19 @@ public class PSurfaceJOGL implements PSurface {
}
if (!sketch.finished) {
- pgl.getGL(drawable);
- int prevFrameCount = sketch.frameCount;
- sketch.handleDraw();
- if (prevFrameCount == sketch.frameCount || sketch.finished) {
- // This hack allows the FBO layer to be swapped normally even if
- // the sketch is no looping or finished because it does not call draw(),
- // otherwise background artifacts may occur (depending on the hardware/drivers).
- pgl.beginRender();
- pgl.endRender(sketch.sketchWindowColor());
+ synchronized (getSyncMutex(drawable)) {
+ pgl.getGL(drawable);
+ int prevFrameCount = sketch.frameCount;
+ sketch.handleDraw();
+ if (prevFrameCount == sketch.frameCount || sketch.finished) {
+ // This hack allows the FBO layer to be swapped normally even if
+ // the sketch is no looping or finished because it does not call draw(),
+ // otherwise background artifacts may occur (depending on the hardware/drivers).
+ pgl.beginRender();
+ pgl.endRender(sketch.sketchWindowColor());
+ }
+ PGraphicsOpenGL.completeFinishedPixelTransfers();
}
- PGraphicsOpenGL.completeFinishedPixelTransfers();
}
if (sketch.exitCalled()) {
@@ -796,24 +839,37 @@ public class PSurfaceJOGL implements PSurface {
}
public void init(GLAutoDrawable drawable) {
- pgl.getGL(drawable);
- pgl.init(drawable);
- sketch.start();
+ if (display.getEDTUtil().isCurrentThreadEDT()) {
+ return;
+ }
- int c = graphics.backgroundColor;
- pgl.clearColor(((c >> 16) & 0xff) / 255f,
- ((c >> 8) & 0xff) / 255f,
- (c & 0xff) / 255f,
- ((c >> 24) & 0xff) / 255f);
- pgl.clear(PGL.COLOR_BUFFER_BIT);
+ synchronized (getSyncMutex(drawable)) {
+ pgl.init(drawable);
+ sketch.start();
+
+ int c = graphics.backgroundColor;
+ pgl.clearColor(((c >> 16) & 0xff) / 255f,
+ ((c >> 8) & 0xff) / 255f,
+ (c & 0xff) / 255f,
+ ((c >> 24) & 0xff) / 255f);
+ pgl.clear(PGL.COLOR_BUFFER_BIT);
+ isInit = true;
+ }
}
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
- pgl.resetFBOLayer();
- pgl.getGL(drawable);
- float scale = PApplet.platform == PConstants.MACOS ?
- getCurrentPixelScale() : getPixelScale();
- setSize((int) (w / scale), (int) (h / scale));
+ if (!isInit) return;
+
+ if (display.getEDTUtil().isCurrentThreadEDT()) {
+ return;
+ }
+
+ synchronized (getSyncMutex(drawable)) {
+ pgl.resetFBOLayer();
+ float scale = PApplet.platform == PConstants.MACOS ?
+ getCurrentPixelScale() : getPixelScale();
+ setSize((int) (w / scale), (int) (h / scale));
+ }
}
}
diff --git a/core/todo.txt b/core/todo.txt
index d944a30b4..b77e61e6b 100644
--- a/core/todo.txt
+++ b/core/todo.txt
@@ -3,10 +3,16 @@ X support extensions for directories with listFiles/listPaths
X otherwise asking for .jpg will return root folders (unless 'only files' specified)
X but because macOS actually puts extensions on folders (.app, etc), support it
X fix for disableStyle() with 2D shapes in P3D
+X allow GEOMETRY (not just PATH) with contains() in PShape
+X the method is still incomplete, but added a note about that too
X added workaround in PShapeOpenGL to get access to vertex data
_ still need to find the root cause
_ also need to check for other reports about this
+X multiple windows with GL
+_ https://github.com/processing/processing4/issues/312
+X https://github.com/processing/processing4/pull/313
+
_ made DrawListener public in PSurfaceJOGL (probably change that back)
diff --git a/java/libraries/dxf/processing4-dxf.iml b/java/libraries/dxf/processing4-dxf.iml
new file mode 100644
index 000000000..97b6e2863
--- /dev/null
+++ b/java/libraries/dxf/processing4-dxf.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/libraries/javafx/processing4-javafx.iml b/java/libraries/javafx/processing4-javafx.iml
new file mode 100644
index 000000000..e169dfb69
--- /dev/null
+++ b/java/libraries/javafx/processing4-javafx.iml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/libraries/net/processing4-net.iml b/java/libraries/net/processing4-net.iml
new file mode 100644
index 000000000..97b6e2863
--- /dev/null
+++ b/java/libraries/net/processing4-net.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/libraries/pdf/processing4-pdf.iml b/java/libraries/pdf/processing4-pdf.iml
new file mode 100644
index 000000000..5d6ac8011
--- /dev/null
+++ b/java/libraries/pdf/processing4-pdf.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/libraries/serial/processing4-serial.iml b/java/libraries/serial/processing4-serial.iml
new file mode 100644
index 000000000..0ca1d9326
--- /dev/null
+++ b/java/libraries/serial/processing4-serial.iml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/libraries/svg/processing4-svg.iml b/java/libraries/svg/processing4-svg.iml
new file mode 100644
index 000000000..484404723
--- /dev/null
+++ b/java/libraries/svg/processing4-svg.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/processing4-java.iml b/java/processing4-java.iml
new file mode 100644
index 000000000..e0c6cdc50
--- /dev/null
+++ b/java/processing4-java.iml
@@ -0,0 +1,181 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file