mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
Merge branch 'processing:master' into p4-new_pshape_api-stream_copy
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)) &&
|
||||
|
||||
@@ -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<FPSAnimator> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user