import java.util.*; import java.util.zip.*; import java.util.List; import java.util.regex.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import java.util.concurrent.locks.*; import java.util.function.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import javax.swing.table.*; import java.io.*; import java.net.*; import java.lang.reflect.*; import java.lang.ref.*; import java.lang.management.*; import java.security.*; import java.security.spec.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.awt.geom.*; import javax.imageio.*; import java.math.*; import java.time.Duration; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.curve.opengl.RenderState; import com.jogamp.graph.geom.SVertex; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.*; import com.jogamp.opengl.fixedfunc.GLMatrixFunc; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.PMVMatrix; class main { // OpenGL static class OpenGL_DemoObjects implements GLEventListener, IFieldsToList{ Animator animator; OpenGL_DemoObjects() {} OpenGL_DemoObjects(Animator animator) { this.animator = animator;} public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + animator + ")"; }public Object[] _fieldsToList() { return new Object[] {animator}; } // these will define a shape that is defined once at init OutlineShape outlineShape; RenderState renderState; RegionRenderer regionRenderer; GLRegion glRegion; // these will define a shape that is updated dynamically for each frame OutlineShape dynamicOutlineShape; RenderState dynamicRenderState; RegionRenderer dynamicRegionRenderer; GLRegion dynamicGlRegion; volatile float weight = 1.0f; final float zNear = 0.1f, zFar = 7000f; /* 2nd pass texture size antialias SampleCount 4 is usually enough */ private final int[] sampleCount = new int[] { 4 }; /* variables used to update the PMVMatrix before rendering */ private float xTranslate = -40f; private float yTranslate = 0f; private float zTranslate = -100f; private float angleRotate = 0f; private final int renderModes = Region.VARWEIGHT_RENDERING_BIT; @Override public void init(GLAutoDrawable drawable) { final GL2ES2 gl = drawable.getGL().getGL2ES2(); gl.setSwapInterval(1); gl.glEnable(GL.GL_DEPTH_TEST); gl.glEnable(GL.GL_BLEND); gl.glClearColor(1.0f, 0.0f, 1.0f, 1.0f); /* initialize OpenGL specific classes that know how to render the graph API shapes */ renderState = RenderState.createRenderState(SVertex.factory()); // define a colour to render our shape with renderState.setColorStatic(1.0f, 1.0f, 1.0f, 1.0f); renderState.setHintMask(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED); /* use the generic graph API to define a shape * we use the renderState getVertexFactory * to automatically store all vertex data on the GPU **/ outlineShape = new OutlineShape(renderState.getVertexFactory()); // Here i add some points off curve causing nurbs bends outlineShape.addEmptyOutline(); outlineShape.addVertex(0.0f,-10.0f, true); outlineShape.addVertex(17.0f,-10.0f, true); outlineShape.addVertex(11.0f,5.0f, /* onCurve */false); outlineShape.addVertex(17.0f,10.0f, true); outlineShape.addVertex(7.0f,15.0f, /* onCurve */ false); outlineShape.addVertex(6.0f,8.0f, /* onCurve */false); outlineShape.addVertex(0.0f,10.0f,true); outlineShape.closeLastOutline(true); // Here i add all points on curve == straight lines float offset = 30; outlineShape.addEmptyOutline(); outlineShape.addVertex(offset+0.0f,-10.0f, true); outlineShape.addVertex(offset+17.0f,-10.0f, true); outlineShape.addVertex(offset+11.0f,5.0f, true); outlineShape.addVertex(offset+16.0f,10.0f, true); outlineShape.addVertex(offset+7.0f,15.0f, true); outlineShape.addVertex(offset+6.0f,8.0f, true); outlineShape.addVertex(offset+0.0f,10.0f, true); outlineShape.closeLastOutline(true); regionRenderer = RegionRenderer.create(renderState, /* GLCallback */ RegionRenderer.defaultBlendEnable, /* GLCallback */ RegionRenderer.defaultBlendDisable); glRegion = GLRegion.create(/* RenderModes */ renderModes, /* TextureSequence */ null); glRegion.addOutlineShape(outlineShape, null, glRegion.hasColorChannel() ? renderState.getColorStatic(new float[4]) : null); /* initialize OpenGL specific classes that know how to render the graph API shapes */ dynamicRenderState = RenderState.createRenderState(SVertex.factory()); // define a RED colour to render our shape with dynamicRenderState.setColorStatic(1.0f, 0.0f, 0.0f, 1.0f); dynamicRenderState.setHintMask(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED); dynamicRegionRenderer = RegionRenderer.create(dynamicRenderState, /* GLCallback */ RegionRenderer.defaultBlendEnable, /* GLCallback */ RegionRenderer.defaultBlendDisable); // we will fill the OutlineShape dynamically in display dynamicOutlineShape = new OutlineShape(dynamicRenderState.getVertexFactory()); dynamicGlRegion = GLRegion.create(/* RenderModes */ renderModes, /* TextureSequence */ null); } @Override public void dispose(GLAutoDrawable drawable) { final GL2ES2 gl = drawable.getGL().getGL2ES2(); //stop the animator thread when user close the window { if (animator != null) animator.stop(); } // it is important to free memory allocated no the GPU! // this memory cant be garbage collected by the JVM regionRenderer.destroy(gl); glRegion.destroy(gl); dynamicGlRegion.destroy(gl); } @Override public void display(GLAutoDrawable drawable) { final GL2ES2 gl = drawable.getGL().getGL2ES2(); // use JogAmp high resolution timer for smooth animations! double time = com.jogamp.common.os.Platform.currentTimeMicros(); float sinusAnimation = (float) (Math.sin(time/100000f)); float sinusAnimationRotate = (float) (Math.sin(time/1000000f)); // clear screen gl.glClearColor(0.2f, 0.2f, 0.2f, 1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // the RegionRenderer PMVMatrix define where we want to render our shape final PMVMatrix pmv = regionRenderer.getMatrix(); pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); pmv.glLoadIdentity(); pmv.glTranslatef(xTranslate, yTranslate, zTranslate); pmv.glRotatef(angleRotate+ 10f * sinusAnimationRotate, 0, 0, 1); if( weight != regionRenderer.getRenderState().getWeight() ) { regionRenderer.getRenderState().setWeight(weight); } // Draw the static shape using RegionRenderer and GLRegion regionRenderer.enable(gl, true); glRegion.draw(gl, regionRenderer, sampleCount); regionRenderer.enable(gl, false); float offset = 60; // We will now update the dynamic shape that changes on each frame // I will animate the off curve points dynamicOutlineShape.clear(); dynamicOutlineShape.addVertex(offset + 0.0f,-10.0f, true); dynamicOutlineShape.addVertex(offset + 17.0f,-10.0f, true); dynamicOutlineShape.addVertex(offset + 11.0f +5 * sinusAnimation,5.0f + 5 * sinusAnimation, /* onCurve */false); dynamicOutlineShape.addVertex(offset + 17.0f,10.0f, true); dynamicOutlineShape.addVertex(offset + 7.0f + 5 * sinusAnimation,15.0f + 5 * sinusAnimation, /* onCurve */ false); dynamicOutlineShape.addVertex(offset + 6.0f ,8.0f , true); dynamicOutlineShape.addVertex(offset + 0.0f,10.0f, true); dynamicOutlineShape.closeLastOutline(true); // the RegionRenderer PMVMatrix define where we want to render our shape final PMVMatrix dynamicPmv = dynamicRegionRenderer.getMatrix(); dynamicPmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); dynamicPmv.glLoadIdentity(); dynamicPmv.glTranslatef(xTranslate, yTranslate, zTranslate); dynamicPmv.glRotatef(angleRotate+ 10f * sinusAnimationRotate, 0, 0, 1); if( weight != dynamicRegionRenderer.getRenderState().getWeight() ) { dynamicRegionRenderer.getRenderState().setWeight(weight); } // when changing the OutlineShape dynamically it is very important that you clear the GPU from old data dynamicGlRegion.clear(gl); // here we upload the new dynamically created data to the GPU dynamicGlRegion.addOutlineShape(dynamicOutlineShape, null, glRegion.hasColorChannel() ? renderState.getColorStatic(new float[4]) : null); // Draw the dynamic shape using RegionRenderer and GLRegion dynamicRegionRenderer.enable(gl, true); dynamicGlRegion.draw(gl, dynamicRegionRenderer, sampleCount); dynamicRegionRenderer.enable(gl, false); } @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { final PMVMatrix pmv = regionRenderer.getMatrix(); regionRenderer.reshapePerspective(45.0f, width, height, zNear, zFar); pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); pmv.glLoadIdentity(); final PMVMatrix dynamicPmv = dynamicRegionRenderer.getMatrix(); dynamicRegionRenderer.reshapePerspective(45.0f, width, height, zNear, zFar); dynamicPmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); dynamicPmv.glLoadIdentity(); } } static String shortClassName_dropNumberPrefix(Object o) { return dropNumberPrefix(shortClassName(o)); } static String dropNumberPrefix(String s) { return dropFirst(s, indexOfNonDigit(s)); } static String shortClassName(Object o) { if (o == null) return null; Class c = o instanceof Class ? (Class) o : o.getClass(); String name = c.getName(); return shortenClassName(name); } static String[] dropFirst(int n, String[] a) { return drop(n, a); } static String[] dropFirst(String[] a) { return drop(1, a); } static Object[] dropFirst(Object[] a) { return drop(1, a); } static List dropFirst(List l) { return dropFirst(1, l); } static List dropFirst(int n, Iterable i) { return dropFirst(n, toList(i)); } static List dropFirst(Iterable i) { return dropFirst(toList(i)); } static List dropFirst(int n, List l) { return n <= 0 ? l : new ArrayList(l.subList(Math.min(n, l.size()), l.size())); } static List dropFirst(List l, int n) { return dropFirst(n, l); } static String dropFirst(int n, String s) { return substring(s, n); } static String dropFirst(String s, int n) { return substring(s, n); } static String dropFirst(String s) { return substring(s, 1); } static int indexOfNonDigit(String s) { int n = l(s); for (int i = 0; i < n; i++) if (!isDigit(s.charAt(i))) return i; return -1; } static String shortenClassName(String name) { if (name == null) return null; int i = lastIndexOf(name, "$"); if (i < 0) i = lastIndexOf(name, "."); return i < 0 ? name : substring(name, i+1); } static String[] drop(int n, String[] a) { n = Math.min(n, a.length); String[] b = new String[a.length-n]; System.arraycopy(a, n, b, 0, b.length); return b; } static Object[] drop(int n, Object[] a) { n = Math.min(n, a.length); Object[] b = new Object[a.length-n]; System.arraycopy(a, n, b, 0, b.length); return b; } static ArrayList toList(A[] a) { return asList(a); } static ArrayList toList(int[] a) { return asList(a); } static ArrayList toList(Set s) { return asList(s); } static ArrayList toList(Iterable s) { return asList(s); } static String substring(String s, int x) { return substring(s, x, strL(s)); } static String substring(String s, int x, int y) { if (s == null) return null; if (x < 0) x = 0; int n = s.length(); if (y < x) y = x; if (y > n) y = n; if (x >= y) return ""; return s.substring(x, y); } // convenience method for quickly dropping a prefix static String substring(String s, CharSequence l) { return substring(s, lCharSequence(l)); } static int l(Object[] a) { return a == null ? 0 : a.length; } static int l(boolean[] a) { return a == null ? 0 : a.length; } static int l(byte[] a) { return a == null ? 0 : a.length; } static int l(short[] a) { return a == null ? 0 : a.length; } static int l(long[] a) { return a == null ? 0 : a.length; } static int l(int[] a) { return a == null ? 0 : a.length; } static int l(float[] a) { return a == null ? 0 : a.length; } static int l(double[] a) { return a == null ? 0 : a.length; } static int l(char[] a) { return a == null ? 0 : a.length; } static int l(Collection c) { return c == null ? 0 : c.size(); } static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible static int l(Map m) { return m == null ? 0 : m.size(); } static int l(CharSequence s) { return s == null ? 0 : s.length(); } static long l(File f) { return f == null ? 0 : f.length(); } static boolean isDigit(char c) { return Character.isDigit(c); } static int lastIndexOf(String a, String b) { return a == null || b == null ? -1 : a.lastIndexOf(b); } static int lastIndexOf(String a, char b) { return a == null ? -1 : a.lastIndexOf(b); } // starts searching from i-1 static int lastIndexOf(List l, int i, A a) { if (l == null) return -1; for (i = min(l(l), i)-1; i >= 0; i--) if (eq(l.get(i), a)) return i; return -1; } static int lastIndexOf(List l, A a) { if (l == null) return -1; for (int i = l(l)-1; i >= 0; i--) if (eq(l.get(i), a)) return i; return -1; } // unclear semantics as to whether return null on null static ArrayList asList(A[] a) { return a == null ? new ArrayList() : new ArrayList(Arrays.asList(a)); } static ArrayList asList(int[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (int i : a) l.add(i); return l; } static ArrayList asList(long[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (long i : a) l.add(i); return l; } static ArrayList asList(float[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (float i : a) l.add(i); return l; } static ArrayList asList(double[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (double i : a) l.add(i); return l; } static ArrayList asList(short[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (short i : a) l.add(i); return l; } static ArrayList asList(Iterator it) { ArrayList l = new ArrayList(); if (it != null) while (it.hasNext()) l.add(it.next()); return l; } // disambiguation static ArrayList asList(IterableIterator s) { return asList((Iterator) s); } static ArrayList asList(Iterable s) { if (s instanceof ArrayList) return (ArrayList) s; ArrayList l = new ArrayList(); if (s != null) for (A a : s) l.add(a); return l; } static ArrayList asList(Enumeration e) { ArrayList l = new ArrayList(); if (e != null) while (e.hasMoreElements()) l.add(e.nextElement()); return l; } static int strL(String s) { return s == null ? 0 : s.length(); } static int lCharSequence(CharSequence s) { return s == null ? 0 : s.length(); } static int iteratorCount_int_close(Iterator i) { try { int n = 0; if (i != null) while (i.hasNext()) { i.next(); ++n; } if (i instanceof AutoCloseable) ((AutoCloseable) i).close(); return n; } catch (Exception __e) { throw rethrow(__e); } } static int min(int a, int b) { return Math.min(a, b); } static long min(long a, long b) { return Math.min(a, b); } static float min(float a, float b) { return Math.min(a, b); } static float min(float a, float b, float c) { return min(min(a, b), c); } static double min(double a, double b) { return Math.min(a, b); } static double min(double[] c) { double x = Double.MAX_VALUE; for (double d : c) x = Math.min(x, d); return x; } static float min(float[] c) { float x = Float.MAX_VALUE; for (float d : c) x = Math.min(x, d); return x; } static byte min(byte[] c) { byte x = 127; for (byte d : c) if (d < x) x = d; return x; } static short min(short[] c) { short x = 0x7FFF; for (short d : c) if (d < x) x = d; return x; } static int min(int[] c) { int x = Integer.MAX_VALUE; for (int d : c) if (d < x) x = d; return x; } static boolean eq(Object a, Object b) { return a == b || a != null && b != null && a.equals(b); } static ArrayList emptyList() { return new ArrayList(); //ret Collections.emptyList(); } static ArrayList emptyList(int capacity) { return new ArrayList(max(0, capacity)); } // Try to match capacity static ArrayList emptyList(Iterable l) { return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList(); } static ArrayList emptyList(Object[] l) { return emptyList(l(l)); } // get correct type at once static ArrayList emptyList(Class c) { return new ArrayList(); } static List ll(A... a) { ArrayList l = new ArrayList(a.length); if (a != null) for (A x : a) l.add(x); return l; } static RuntimeException rethrow(Throwable t) { if (t instanceof Error) _handleError((Error) t); throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } static RuntimeException rethrow(String msg, Throwable t) { throw new RuntimeException(msg, t); } static String str(Object o) { return o == null ? "null" : o.toString(); } static String str(char[] c) { return new String(c); } static String str(char[] c, int offset, int count) { return new String(c, offset, count); } static int max(int a, int b) { return Math.max(a, b); } static int max(int a, int b, int c) { return max(max(a, b), c); } static long max(int a, long b) { return Math.max((long) a, b); } static long max(long a, long b) { return Math.max(a, b); } static double max(int a, double b) { return Math.max((double) a, b); } static float max(float a, float b) { return Math.max(a, b); } static double max(double a, double b) { return Math.max(a, b); } static > A max (Iterable l) { A max = null; var it = iterator(l); if (it.hasNext()) { max = it.next(); while (it.hasNext()) { A a = it.next(); if (cmp(a, max) > 0) max = a; } } return max; } /*Nah. static int max(Collection c) { int x = Integer.MIN_VALUE; for (int i : c) x = max(x, i); ret x; }*/ static double max(double[] c) { if (c.length == 0) return Double.MIN_VALUE; double x = c[0]; for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); return x; } static float max(float[] c) { if (c.length == 0) return Float.MAX_VALUE; float x = c[0]; for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); return x; } static byte max(byte[] c) { byte x = -128; for (byte d : c) if (d > x) x = d; return x; } static short max(short[] c) { short x = -0x8000; for (short d : c) if (d > x) x = d; return x; } static int max(int[] c) { int x = Integer.MIN_VALUE; for (int d : c) if (d > x) x = d; return x; } static > A max(A a, A b) { return cmp(a, b) >= 0 ? a : b; } static void _handleError(Error e) { //call(javax(), '_handleError, e); } static Iterator iterator(Iterable c) { return c == null ? emptyIterator() : c.iterator(); } static int cmp(Number a, Number b) { return a == null ? b == null ? 0 : -1 : cmp(a.doubleValue(), b.doubleValue()); } static int cmp(double a, double b) { return a < b ? -1 : a == b ? 0 : 1; } static int cmp(int a, int b) { return a < b ? -1 : a == b ? 0 : 1; } static int cmp(long a, long b) { return a < b ? -1 : a == b ? 0 : 1; } static int cmp(Object a, Object b) { if (a == null) return b == null ? 0 : -1; if (b == null) return 1; return ((Comparable) a).compareTo(b); } static Iterator emptyIterator() { return Collections.emptyIterator(); } static interface IFieldsToList { Object[] _fieldsToList(); } // you still need to implement hasNext() and next() static abstract class IterableIterator implements Iterator, Iterable { public Iterator iterator() { return this; } public void remove() { unsupportedOperation(); } } static UnsupportedOperationException unsupportedOperation() { throw new UnsupportedOperationException(); } }