28package com.jogamp.graph.ui;
31import java.nio.ByteBuffer;
32import java.util.ArrayList;
33import java.util.Arrays;
34import java.util.Collection;
35import java.util.Comparator;
37import java.util.Locale;
38import java.util.concurrent.CopyOnWriteArrayList;
39import java.util.concurrent.atomic.AtomicReference;
41import com.jogamp.opengl.FPSCounter;
42import com.jogamp.opengl.GL;
43import com.jogamp.opengl.GL2ES2;
44import com.jogamp.opengl.GLAutoDrawable;
45import com.jogamp.opengl.GLCapabilitiesImmutable;
46import com.jogamp.opengl.GLEventListener;
47import com.jogamp.opengl.GLException;
48import com.jogamp.opengl.GLProfile;
49import com.jogamp.opengl.GLRunnable;
50import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
51import com.jogamp.common.nio.Buffers;
52import com.jogamp.common.os.Platform;
53import com.jogamp.graph.curve.Region;
54import com.jogamp.graph.curve.opengl.GLRegion;
55import com.jogamp.graph.curve.opengl.RegionRenderer;
56import com.jogamp.graph.curve.opengl.RenderState;
57import com.jogamp.math.FloatUtil;
58import com.jogamp.math.Matrix4f;
59import com.jogamp.math.Ray;
60import com.jogamp.math.Recti;
61import com.jogamp.math.Vec2f;
62import com.jogamp.math.Vec3f;
63import com.jogamp.math.geom.AABBox;
64import com.jogamp.math.util.PMVMatrix4f;
65import com.jogamp.newt.event.GestureHandler;
66import com.jogamp.newt.event.InputEvent;
67import com.jogamp.newt.event.KeyEvent;
68import com.jogamp.newt.event.KeyListener;
69import com.jogamp.newt.event.MouseEvent;
70import com.jogamp.newt.event.MouseListener;
71import com.jogamp.newt.event.PinchToZoomGesture;
72import com.jogamp.newt.event.GestureHandler.GestureEvent;
73import com.jogamp.newt.opengl.GLWindow;
74import com.jogamp.opengl.util.GLPixelStorageModes;
75import com.jogamp.opengl.util.GLReadBufferUtil;
76import com.jogamp.opengl.util.texture.TextureSequence;
78import jogamp.graph.ui.TreeTool;
131 private static final boolean DEBUG =
false;
132 private static final boolean DEBUG_PICKING = DEBUG;
134 private final List<Shape> shapes =
new CopyOnWriteArrayList<Shape>();
135 private Shape[] displayShapeArray =
new Shape[0];
136 private final List<Shape> renderedShapesB0 =
new ArrayList<Shape>();
137 private final List<Shape> renderedShapesB1 =
new ArrayList<Shape>();
138 private final List<Shape> renderedShapesB2 =
new ArrayList<Shape>();
139 private volatile List<Shape> renderedShapes = renderedShapesB1;
140 private int renderedShapesIdx = 1;
141 private final AtomicReference<Tooltip> toolTipActive =
new AtomicReference<Tooltip>();
142 private final AtomicReference<Shape> toolTipHUD =
new AtomicReference<Shape>();
143 private final List<Group> topLevel =
new ArrayList<Group>();
145 private boolean doFrustumCulling =
false;
147 private float[] clearColor =
null;
148 private int clearMask;
153 private final AABBox planeBox =
new AABBox(0f, 0f, 0f, 0f, 0f, 0f);
155 private volatile Shape activeShape =
null;
156 private volatile Group activeTopLevel =
null;
158 private SBCMouseListener sbcMouseListener =
null;
159 private SBCGestureListener sbcGestureListener =
null;
161 private SBCKeyListener sbcKeyListener =
null;
178 this( createRenderer() );
189 public Scene(
final int sampleCount) {
190 this( createRenderer() );
201 if(
null == renderer ) {
202 throw new IllegalArgumentException(
"Null RegionRenderer");
204 this.renderer = renderer;
205 if( Platform.OSType.ANDROID != Platform.getOSType() ) {
208 this.screenshot =
null;
226 public final void setClearParams(
final float[] clearColor,
final int clearMask) { this.clearColor = clearColor; this.clearMask = clearMask; }
244 cDrawable = drawable;
247 if( cDrawable == drawable ) {
253 if(
null == sbcMouseListener) {
254 sbcMouseListener =
new SBCMouseListener();
256 sbcGestureListener =
new SBCGestureListener();
261 if(
null == sbcKeyListener) {
262 sbcKeyListener =
new SBCKeyListener();
268 if(
null != sbcMouseListener) {
270 sbcMouseListener =
null;
272 sbcGestureListener =
null;
274 pinchToZoomGesture =
null;
276 if(
null == sbcKeyListener) {
278 sbcKeyListener =
null;
298 if( shapes.remove(s) ) {
307 for(
final Shape s : shapes) {
314 if( shapes.remove(s) ) {
327 public void addShapes(
final Collection<? extends Shape> shapes) {
328 for(
final Shape s : shapes) {
334 for(
final Shape s : shapes) {
344 final int count = shapes.size();
345 for(
int i=count-1; i>=0; --i) {
356 return TreeTool.contains(
this, s);
363 return shapes.get(
id);
367 return TreeTool.getShapeByID(
this,
id);
371 return TreeTool.getShapeByName(
this, name);
391 TreeTool.forAll(
this, (
final Shape s) -> {
399 TreeTool.forAll(
this, (
final Shape s) -> {
405 TreeTool.forAll(
this, (
final Shape s) -> {
413 if(
null == cDrawable ) {
414 cDrawable = drawable;
433 public boolean invoke(
final boolean wait,
final GLRunnable glRunnable)
throws IllegalStateException {
434 if(
null != cDrawable ) {
435 return cDrawable.
invoke(wait, glRunnable);
441 if(
null != cDrawable ) {
446 if(
null != cDrawable ) {
472 if( doFrustumCulling ){
484 if( doFrustumCulling ){
493 final int shapeCount = shapes.size();
494 Arrays.fill(displayShapeArray,
null);
495 final Shape[] shapeArray = shapes.toArray(displayShapeArray);
496 displayShapeArray = shapeArray;
503 final List<Shape> iShapes;
505 switch(renderedShapesIdx) {
506 case 0: iShapeIdx = 1; iShapes = renderedShapesB1;
break;
507 case 1: iShapeIdx = 2; iShapes = renderedShapesB2;
break;
508 default: iShapeIdx = 0; iShapes = renderedShapesB0;
break;
510 if(
null != clearColor ) {
511 gl.
glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
514 renderer.
enable(gl,
true);
516 synchronized( iShapes ) {
519 for(
int i=0; i<shapeCount; i++) {
520 final Shape shape = shapeArray[i];
526 shape.
draw(gl, renderer);
537 renderer.
enable(gl,
false);
538 renderedShapes = iShapes;
539 renderedShapesIdx = iShapeIdx;
541 synchronized ( syncDisplayedOnce ) {
542 displayedOnce =
true;
543 syncDisplayedOnce.notifyAll();
545 final Tooltip tt = toolTipActive.get();
547 activateTooltipImpl(drawable, pmv, tt);
551 private void displayGLSelect(
final GLAutoDrawable drawable,
final Object[] shapes) {
561 final int shapeCount = shapes.length;
562 for(
int i=0; i<shapeCount; i++) {
569 final float color = ( i + 1f ) / ( shapeCount + 2f );
578 renderer.
enable(gl,
false, RegionRenderer.defaultBlendDisable, RegionRenderer.defaultBlendDisable);
579 synchronized ( syncDisplayedOnce ) {
580 displayedOnce =
true;
581 syncDisplayedOnce.notifyAll();
585 private volatile boolean displayedOnce =
false;
586 private final Object syncDisplayedOnce =
new Object();
590 synchronized( syncDisplayedOnce ) {
591 while( !displayedOnce ) {
593 syncDisplayedOnce.wait();
594 }
catch (
final InterruptedException e) { }
611 synchronized ( syncDisplayedOnce ) {
612 displayedOnce =
false;
613 syncDisplayedOnce.notifyAll();
615 if( drawable instanceof
GLWindow ) {
620 for(
int i=0; i<shapes.size(); i++) {
621 shapes.get(i).destroy(gl, renderer);
623 for(
int i=0; i<disposeActions.size(); i++) {
625 disposeActions.get(i).run(drawable);
626 }
catch(
final Throwable t) {
627 System.err.println(
"Scene.dispose: Caught Exception @ User Disposable["+i+
"]: "+t.getMessage());
633 displayShapeArray =
new Shape[0];
634 renderedShapesB0.
clear();
635 renderedShapesB1.clear();
636 renderedShapesB2.clear();
637 renderedShapes = renderedShapesB1;
638 renderedShapesIdx = 1;
639 disposeActions.clear();
640 if( drawable == cDrawable ) {
644 if(
null != screenshot ) {
648 private final List<GLRunnable> disposeActions =
new ArrayList<GLRunnable>();
670 if(
null == shape ) {
675 TreeTool.forOne(
this, pmv, shape, () -> {
676 if(
null != shape.
winToShapeCoord(pmv, viewport, glWinX, glWinY, objPos) ) {
685 if(
null == shape ) {
689 TreeTool.forOne(
this, pmv, shape, () -> {
761 pmvMatrixSetup.
set(pmv, viewport);
827 final float zNear,
final float zFar,
828 final float winX,
final float winY,
final float objOrthoZ,
829 final Vec3f objPos) {
831 pmv.
mapWinToObj(winX, winY, winZ, viewport, objPos);
852 objSceneSize.
set( obj11Coord.x() - obj00Coord.x(),
853 obj11Coord.y() - obj00Coord.y() );
872 final Shape lastShape = activeShape;
873 if(
null != lastShape ) {
874 final Group lastTL = activeTopLevel;
878 activeTopLevel =
null;
879 if(
null != lastTL ) {
880 lastTL.setActiveTopLevel(
false, 0);
882 if( DEBUG_PICKING ) {
883 System.err.println(
"ACTIVE-RELEASE: s 0x"+Integer.toHexString(System.identityHashCode(lastShape))+
", "+lastShape);
884 System.err.println(
"ACTIVE-RELEASE: g 0x"+Integer.toHexString(System.identityHashCode(lastTL))+
", "+lastTL);
885 dumpTopLevelParent();
889 private void setActiveShape(
final Shape shape) {
890 final Shape lastShape = activeShape;
891 if( lastShape != shape &&
null != shape ) {
893 final boolean isTopLevel = topLevel.contains(shape);
894 final float newZOffset = ( isTopLevel ? activeZOffsetScale : activeTopLevelZOffsetScale ) * zEpsilon;
895 if( shape.
setActive(
true, newZOffset) ) {
896 final Group lastTL = activeTopLevel;
897 final Group thisTL = isTopLevel ? (
Group)shape : getTopLevelParent(shape);
899 if(
null != lastShape && thisTL != lastShape ) {
903 if( lastTL != thisTL ) {
906 lastTL.setActiveTopLevel(
false, 0);
909 if(
null!=thisTL && !isTopLevel ) {
910 thisTL.setActiveTopLevel(
true, activeTopLevelZOffsetScale * zEpsilon);
913 activeTopLevel = thisTL;
916 if( DEBUG_PICKING ) {
917 System.err.println(
"ACTIVE-SHAPE: NEW mode "+mode+
", isTopLevel "+isTopLevel+
", s 0x"+Integer.toHexString(System.identityHashCode(shape))+
", "+shape);
918 System.err.println(
"ACTIVE-SHAPE: NEW g 0x"+Integer.toHexString(System.identityHashCode(thisTL))+
", "+thisTL);
919 System.err.println(
"ACTIVE-SHAPE: PRE s 0x"+Integer.toHexString(System.identityHashCode(lastShape))+
", "+lastShape);
920 System.err.println(
"ACTIVE-SHAPE: PRE g 0x"+Integer.toHexString(System.identityHashCode(lastTL))+
", "+lastTL);
941 void addTopLevel(
final Group g) { topLevel.add(g); }
942 void removeTopLevel(
final Group g) { topLevel.add(g); }
943 private Group getTopLevelParent(
final Shape s) {
944 for(
final Group g : topLevel) {
951 private void dumpTopLevelParent() {
953 for(
final Group g : topLevel) {
954 final boolean a0 = g.isActive();
955 System.err.printf(
"- %02d: 0x%08x %s %s/%s, %s%n", idx++, System.identityHashCode(g), (a0?
"****":
"____"), g.getClass().getSimpleName(), g.getName(), g);
957 final int idx1 = idx-1;
958 final int[] idx2 = { 0 };
959 TreeTool.forAll(g, (
final Shape s) -> {
960 final boolean a1 = s.isActive();
961 System.err.printf(
"- %02d:%02d: 0x%08x %s %s/%s, %s%n", idx1, idx2[0]++, System.identityHashCode(s), (a1?
"****":
"____"), s.getClass().getSimpleName(), s.getName(), s);
968 private final class SBCGestureListener
implements GestureHandler.GestureListener {
970 public void gestureDetected(
final GestureEvent gh) {
972 if(
null != activeShape ) {
974 final InputEvent orig = gh.getTrigger();
975 if( orig instanceof MouseEvent ) {
976 final Shape shape = activeShape;
977 if( shape.isInteractive() ) {
978 final MouseEvent e = (MouseEvent) orig;
980 final int glWinX = e.getX();
981 final int glWinY =
getHeight() - e.getY() - 1;
982 final PMVMatrix4f pmv =
new PMVMatrix4f();
983 final Vec3f objPos =
new Vec3f();
985 shape.dispatchGestureEvent(gh, glWinX, glWinY, pmv, renderer.
getViewport(), objPos);
1007 public void pickShapeGL(
final int glWinX,
final int glWinY,
final Vec3f objPos,
final Shape[] shape,
final Runnable runnable) {
1008 if(
null == cDrawable ) {
1014 final Shape s = pickShapeGLImpl(drawable, glWinX, glWinY);
1029 @SuppressWarnings({
"unchecked",
"rawtypes" })
1030 private Shape pickShapeGLImpl(
final GLAutoDrawable drawable,
final int glWinX,
final int glWinY) {
1031 final Object[] shapesS = shapes.toArray();
1032 Arrays.sort(shapesS, (Comparator)Shape.ZAscendingComparator);
1034 final GLPixelStorageModes psm =
new GLPixelStorageModes();
1035 final ByteBuffer pixel = Buffers.newDirectByteBuffer(4);
1039 displayGLSelect(drawable, shapesS);
1041 psm.setPackAlignment(gl, 4);
1045 gl.glReadPixels(glWinX, glWinY, 1, 1, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixel);
1046 }
catch(
final GLException gle) {
1047 gle.printStackTrace();
1053 final int shapeCount = shapes.size();
1054 final int qp = pixel.get(0) & 0xFF;
1055 final float color = qp / 255.0f;
1056 final int index = Math.round( ( color * ( shapeCount + 2f) ) - 1f );
1059 System.err.printf(
"pickGL: glWin %d / %d, byte %d, color %f, index %d of [0..%d[%n",
1060 glWinX, glWinY, qp, color, index, shapeCount);
1062 if( 0 <= index && index < shapeCount ) {
1063 return (Shape)shapesS[index];
1072 private static interface PickVisitor {
1079 Shape visit(Shape s,
final PMVMatrix4f pmv);
1081 private static Shape pickForAllRenderedDesc(
final Container cont,
final PMVMatrix4f pmv,
final PickVisitor v) {
1082 Shape picked =
null;
1083 final List<Shape> shapes = cont.getRenderedShapes();
1084 synchronized( shapes ) {
1085 for(
int i=shapes.size()-1;
null == picked && i>=0; --i) {
1086 final Shape s = shapes.get(i);
1088 s.applyMatToMv(pmv);
1089 picked = v.visit(s, pmv);
1090 if( s instanceof Container ) {
1091 final Shape childPick = pickForAllRenderedDesc((Container)s, pmv, v);
1092 if(
null != childPick ) {
1123 final float winZ0 = 0f;
1124 final float winZ1 = 0.3f;
1131 final int[] shapeIdx = { -1 };
1132 return pickForAllRenderedDesc(
this, pmv, (
final Shape s,
final PMVMatrix4f pmv2) -> {
1134 if( pmv.
mapWinToRay(glWinX, glWinY, winZ0, winZ1, viewport, ray) ) {
1135 final AABBox sbox = s.getBounds();
1136 if( sbox.intersectsRay(ray) ) {
1137 if( null == sbox.getRayIntersection(objPos, ray, FloatUtil.EPSILON, true) ) {
1138 throw new InternalError(
"Ray "+ray+
", box "+sbox);
1140 if( visitor.visit(s) ) {
1154 private final Shape dispatchMouseEventPickShape(
final MouseEvent e,
final int glWinX,
final int glWinY) {
1155 final Shape shape = pickShape(dispMEPSPMv, dispMEPSRay, glWinX, glWinY, dispMEPSObjPos, (
final Shape s) -> {
1157 if( !s.isInteractive() ) {
1158 if( DEBUG_PICKING ) {
1159 System.err.printf(
"Pick.X.0: shape %s/%s, [%d, %d]%n", s.getClass().getSimpleName(), s.getName(), glWinX, glWinY);
1163 if( !s.dispatchMouseEvent(e, glWinX, glWinY, dispMEPSObjPos) ) {
1164 if( DEBUG_PICKING ) {
1165 System.err.printf(
"Pick.X.1: shape %s/%s, [%d, %d], %s%n", s.getClass().getSimpleName(), s.getName(), glWinX, glWinY, e);
1169 if( DEBUG_PICKING ) {
1170 System.err.printf(
"Pick.X.S: shape %s/%s, [%d, %d], %s%n", s.getClass().getSimpleName(), s.getName(), glWinX, glWinY, e);
1174 if(
null != shape ) {
1175 if( DEBUG_PICKING ) {
1176 System.err.printf(
"Pick.X: shape %s/%s%n%n", shape.getClass().getSimpleName(), shape.getName());
1178 setActiveShape(shape);
1181 if( DEBUG_PICKING ) {
1182 System.err.printf(
"Pick.X: shape null%n%n");
1184 releaseActiveShape();
1188 private final PMVMatrix4f dispMEPSPMv =
new PMVMatrix4f();
1189 private final Ray dispMEPSRay =
new Ray();
1190 private final Vec3f dispMEPSObjPos =
new Vec3f();
1199 private final void dispatchMouseEventForShape(
final Shape shape,
final MouseEvent e,
final int glWinX,
final int glWinY) {
1200 final PMVMatrix4f pmv =
new PMVMatrix4f();
1201 final Vec3f objPos =
new Vec3f();
1202 winToShapeCoord(shape, glWinX, glWinY, pmv, objPos, () -> { shape.dispatchMouseEvent(e, glWinX, glWinY, objPos); });
1203 if( DEBUG_PICKING ) {
1204 System.err.printf(
"ForShape: shape %s/%s%n%n", shape.getClass().getSimpleName(), shape.getName());
1208 private final class SBCMouseListener
implements MouseListener {
1209 private int lx, ly, lId;
1210 private boolean mouseOver;
1212 private SBCMouseListener() {
1215 private final void clear() {
1216 lx = -1; ly = -1; lId = -1; mouseOver =
false;
1218 private final Shape dispatchPickShape(
final MouseEvent e,
final int glWinX,
final int glWinY) {
1219 final Shape s = dispatchMouseEventPickShape(e, glWinX, glWinY);
1226 public void mousePressed(
final MouseEvent e) {
1227 if( -1 == lId || e.getPointerId(0) == lId ) {
1230 lId = e.getPointerId(0);
1233 final int glWinX = e.getX();
1234 final int glWinY = getHeight() - e.getY() - 1;
1238 dispatchPickShape(e, glWinX, glWinY);
1242 public void mouseReleased(
final MouseEvent e) {
1244 final int glWinX = e.getX();
1245 final int glWinY = getHeight() - e.getY() - 1;
1246 if( mouseOver &&
null != activeShape && activeShape.
isInteractive() && !pinchToZoomGesture.
isWithinGesture() && e.getPointerId(0) == lId ) {
1247 dispatchMouseEventForShape(activeShape, e, glWinX, glWinY);
1249 dispatchPickShape(e, glWinX, glWinY);
1251 if( !mouseOver && 1 == e.getPointerCount() ) {
1253 releaseActiveShape();
1259 public void mouseClicked(
final MouseEvent e) {
1261 final int glWinX = e.getX();
1262 final int glWinY = getHeight() - e.getY() - 1;
1266 dispatchPickShape(e, glWinX, glWinY);
1270 public void mouseDragged(
final MouseEvent e) {
1279 final int glWinX = e.getX();
1280 final int glWinY = getHeight() - e.getY() - 1;
1281 dispatchMouseEventForShape(activeShape, e, glWinX, glWinY);
1286 public void mouseWheelMoved(
final MouseEvent e) {
1289 final int glWinX = lx;
1290 final int glWinY = getHeight() - ly - 1;
1291 if( mouseOver &&
null != activeShape && activeShape.
isInteractive() && !pinchToZoomGesture.
isWithinGesture() && e.getPointerId(0) == lId ) {
1292 dispatchMouseEventForShape(activeShape, e, glWinX, glWinY);
1294 dispatchPickShape(e, glWinX, glWinY);
1299 public void mouseMoved(
final MouseEvent e) {
1300 if( -1 == lId || e.getPointerId(0) == lId ) {
1303 lId = e.getPointerId(0);
1306 final int glWinX = lx;
1307 final int glWinY = getHeight() - ly - 1;
1308 final Shape s = dispatchPickShape(e, glWinX, glWinY);
1311 synchronized( toolTipActive ) {
1312 toolTipActive.set( s.startToolTip(
true ) );
1317 public void mouseEntered(
final MouseEvent e) { }
1319 public void mouseExited(
final MouseEvent e) {
1321 releaseActiveShape();
1325 private final class SBCKeyListener
implements KeyListener {
1327 public void keyPressed(
final KeyEvent e) {
1329 activeShape.dispatchKeyEvent(e);
1334 public void keyReleased(
final KeyEvent e) {
1336 activeShape.dispatchKeyEvent(e);
1341 private void setToolTip(
final Shape hud) {
1343 toolTipHUD.set( hud );
1346 private void clearToolTip() {
1348 synchronized( toolTipActive ) {
1349 tt = toolTipActive.get();
1350 if(
null != tt && tt.stop(
false) ) {
1351 toolTipActive.set(
null);
1354 final Shape s = toolTipHUD.getAndSet(
null);
1356 invoke(
false, (
final GLAutoDrawable drawable) -> {
1358 if( s == removeShape(s) ) {
1359 tt.destroyTip(drawable.getGL().getGL2ES2(), renderer, s);
1362 removeShape(drawable.getGL().getGL2ES2(), renderer, s);
1368 private void activateTooltipImpl(
final GLAutoDrawable drawable,
final PMVMatrix4f pmv,
final Tooltip tt) {
1369 if(
null == toolTipHUD.get() ) {
1370 final Shape[] hud = {
null };
1371 if( tt.tick() && TreeTool.forOne(
this, pmv, tt.getTool(), () -> {
1372 final AABBox toolMvBounds = tt.getToolMvBounds(pmv);
1373 hud[0] = tt.createTip(Scene.this, toolMvBounds);
1376 setToolTip( hud[0] );
1390 final float lfps, tfps, td;
1391 if(
null != fpsCounter ) {
1402 final String blendStr;
1404 blendStr =
", blend";
1408 return String.format(
"%03.1f/%03.1f fps, %.1f ms/f, vsync %d, dpi %.1f, %s%s, a %d",
1421 return String.format(
"%03.1f/%03.1f fps, %.1f ms/f", lfps, tfps, td);
1442 final String dir2 = (
null != dir && dir.length() > 0 ) ? dir :
"";
1443 final String prefix2 = (
null != prefix && prefix.length() > 0 ) ? prefix+
"-" :
"";
1446 final String contentDetail2 = (
null != contentDetail && contentDetail.length() > 0 ) ? contentDetail+
"-" :
"";
1447 return new File( String.format((Locale)
null,
"%s%s%s-%ssnap%02d-%04dx%04d.png",
1448 dir2, prefix2, modeS, contentDetail2,
1451 private int screenShotCount = 0;
1471 if(
null != screenshot && screenshot.
readPixels(gl,
false)) {
1472 screenshot.
write(file);
1473 System.err.println(
"Wrote: "+file);
1487 if(
null != cDrawable ) {
1488 cDrawable.
invoke(wait, (drawable) -> {
1489 screenshot(drawable.getGL(), file);
1517 private final float scene_dist;
1519 private final float angle;
1521 private final float zNear;
1523 private final float zFar;
1536 if( !( zNear > 0 && zFar > zNear ) ) {
1537 throw new IllegalArgumentException(
"zNear is "+zNear+
", but must be > 0 and < zFar, zFar "+zFar);
1539 this.scene_dist = scene_dist;
1578 final float ratio = (float) viewport.width() / (float) viewport.height();
1579 pmv.loadPIdentity();
1580 pmv.perspectiveP(angle, ratio, zNear, zFar);
1581 pmv.translateP(0f, 0f, scene_dist);
1583 pmv.loadMvIdentity();
1588 final float orthoDist = -scene_dist;
1592 winToPlaneCoord(pmv, viewport, zNear, zFar, viewport.x(), viewport.y(), orthoDist, obj00Coord);
1593 winToPlaneCoord(pmv, viewport, zNear, zFar, viewport.width(), viewport.height(), orthoDist, obj11Coord);
1595 planeBox.
setSize( obj00Coord, obj11Coord );
1607 private PMVMatrixSetup pmvMatrixSetup =
new DefaultPMVMatrixSetup();
Abstract Outline shape representation define the method an OutlineShape(s) is bound and rendered.
static String getRenderModeString(final int renderModes)
Returns a unique technical description string for renderModes as follows:
final void enable(final GL2ES2 gl, final boolean enable)
Enabling or disabling the RenderState's current shader program.
final int getAAQuality()
Returns pass2 AA-quality rendering value for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT.
final int getHeight()
Return height of current viewport.
final void setColorStatic(final Vec4f rgbaColor)
final PMVMatrix4f getMatrix()
Borrow the current PMVMatrix4f.
final void reshapeNotify(final int x, final int y, final int width, final int height)
No PMVMatrix4f operation is performed here.
final int getWidth()
Return width of current viewport.
final int setSampleCount(final int v)
Sets pass2 AA sample count clipped to the range [Region#MIN_AA_SAMPLE_COUNT..Region#MAX_AA_SAMPLE_COU...
static final GLCallback defaultBlendDisable
Default GL#GL_BLEND disable GLCallback, simply turning-off the GL#GL_BLEND state and turning-on depth...
final int setAAQuality(final int v)
Sets pass2 AA-quality rendering value clipped to the range [Region#MIN_AA_QUALITY....
static final GLCallback defaultBlendEnable
Default GL#GL_BLEND enable GLCallback, turning-off depth writing via GL#glDepthMask(boolean) if Rende...
final void init(final GL2ES2 gl)
Initialize shader and bindings for GPU based rendering bound to the given GL object's GLContext if no...
final int getSampleCount()
Returns pass2 AA sample count for Graph Region AA render-modes: VBAA_RENDERING_BIT or Region#MSAA_REN...
static RegionRenderer create()
Create a hardware accelerated RegionRenderer including its RenderState composition.
final Recti getViewport(final Recti target)
Copies the current Rect4i viewport in given target and returns it for chaining.
final void destroy(final GL2ES2 gl)
Deletes all ShaderPrograms and nullifies its references including RenderState#destroy(GL2ES2).
The RenderState is owned by RegionRenderer.
static final int BITHINT_BLENDING_ENABLED
Bitfield hint, if set stating enabled GL#GL_BLEND, otherwise disabled.
Graph based GLRegion Shape.
Group of Shapes, optionally utilizing a Group.Layout.
Default implementation of Scene.PMVMatrixSetup, implementing Scene.PMVMatrixSetup#set(PMVMatrix4f,...
float getAngle()
Returns fov projection angle in radians, shall be 0 for orthogonal projection.
float getZFar()
Returns projection z-far value.
void setPlaneBox(final AABBox planeBox, final PMVMatrix4f pmv, final Recti viewport)
Optional method to set the Scene#getBounds() AABBox, maybe a nop if not desired.
DefaultPMVMatrixSetup(final float scene_dist, final float zNear, final float zFar, final float angle)
Custom DefaultPMVMatrixSetup instance.
float getSceneDist()
Returns scene distance on z-axis to projection.
DefaultPMVMatrixSetup()
Default DefaultPMVMatrixSetup instance using Scene#DEFAULT_SCENE_DIST, Scene#DEFAULT_ZNEAR,...
DefaultPMVMatrixSetup(final float scene_dist, final float zNear, final float zFar)
Custom DefaultPMVMatrixSetup instance using given scene_dist, zNear, zFar and Scene#DEFAULT_ANGLE.
DefaultPMVMatrixSetup(final float scene_dist)
Custom DefaultPMVMatrixSetup instance using given scene_dist and Scene#DEFAULT_ZNEAR,...
float getZNear()
Returns projection z-near value.
float getZEpsilon(final int zBits)
Return Z precision on using current getPMVMatrixSetup()'s PMVMatrixSetup#getSceneDist() z-position an...
void addShape(final Shape s)
Adds a Shape.
static final float DEFAULT_ACTIVE_ZOFFSET_SCALE
Default Z precision scale, i.e.
void addDisposeAction(final GLRunnable action)
Add a user one-time GLRunnable disposal action to an internal list, all invoked at {@Link dispose(GLA...
static final float DEFAULT_ACTIVE_TOPLEVEL_ZOFFSET_SCALE
Default Z precision scale, i.e.
synchronized void attachGLAutoDrawable(final GLAutoDrawable drawable)
final void setClearParams(final float[] clearColor, final int clearMask)
Sets the clear parameter for glClearColor(..) and glClear(..) to be issued at display(GLAutoDrawable)...
static final float DEFAULT_ZFAR
Default projection z-far value is {@value}.
float getActiveShapeZOffsetScale()
Returns the active Shape Z-Offset scale, defaults to DEFAULT_ACTIVE_ZOFFSET_SCALE.
int setSampleCount(final int v)
Sets RegionRenderer#setSampleCount(int).
boolean isScreenshotSupported()
synchronized void detachInputListenerFrom(final GLWindow window)
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
float getActiveTopLevelZOffsetScale()
Returns the general top-level widget Z-Offset scale, defaults to DEFAULT_ACTIVE_ZOFFSET_SCALE.
Scene()
Create a new scene with an internally created RegionRenderer, a graph AA sample-count 4 and using Def...
int getSampleCount()
Returns RegionRenderer#getSampleCount().
RegionRenderer getRenderer()
Returns the associated RegionRenderer.
void screenshot(final GL gl, final File file)
Write current read drawable (screen) to a file.
static final float DEFAULT_SCENE_DIST
Default scene distance on z-axis to projection is -1/5f.
Shape getShapeByID(final int id)
Shape removeShape(final Shape s)
Removes given shape, w/o Shape#destroy(GL2ES2, RegionRenderer).
List< Shape > getShapes()
Returns added Shapes.
final void setPMvCullingEnabled(final boolean v)
Enable or disable Project-Modelview (PMv) frustum culling per Shape for this container.
int setAAQuality(final int v)
Sets RegionRenderer#setAAQuality(int).
final PMVMatrixSetup getPMVMatrixSetup()
Return the default or setPMVMatrixSetup(PMVMatrixSetup) PMVMatrixSetup.
static void winToPlaneCoord(final PMVMatrix4f pmv, final Recti viewport, final float zNear, final float zFar, final float winX, final float winY, final float objOrthoZ, final Vec3f objPos)
Scene(final int sampleCount)
Create a new scene with an internally created RegionRenderer, using DefaultPMVMatrixSetup#DefaultPMVM...
void dispose(final GLAutoDrawable drawable)
Disposes all added Shapes.
void removeShapes(final GL2ES2 gl, final RegionRenderer renderer, final Collection<? extends Shape > shapes)
Removes all given shapes with Shape#destroy(GL2ES2, RegionRenderer).
Scene(final RegionRenderer renderer)
Create a new scene taking ownership of the given RegionRenderer, using DefaultPMVMatrixSetup#DefaultP...
boolean contains(final Shape s)
void waitUntilDisplayed()
Blocks until first display(GLAutoDrawable) has completed after construction or dispose(GLAutoDrawable...
final boolean isOutside(final PMVMatrix4f pmv, final Shape shape)
Returns whether the given Shape is completely outside of this container.
void setupMatrix(final PMVMatrix4f pmv)
Setup PMVMatrix4f GLMatrixFunc#GL_PROJECTION and GLMatrixFunc#GL_MODELVIEW using implicit getViewport...
void setupMatrix(final PMVMatrix4f pmv, final Recti viewport)
Setup PMVMatrix4f GLMatrixFunc#GL_PROJECTION and GLMatrixFunc#GL_MODELVIEW by calling getPMVMatrixSet...
final void setPMVMatrixSetup(final PMVMatrixSetup setup)
Set a custom PMVMatrixSetup.
final Recti getViewport(final Recti target)
Copies the current int[4] viewport in given target and returns it for chaining.
void removeAllShapes(final GL2ES2 gl, final RegionRenderer renderer)
Removes all contained shapes with Shape#destroy(GL2ES2, RegionRenderer).
AABBox getBounds()
Describing the scene's object model-dimensions of the plane at scene-distance covering the visible vi...
void removeAllShapes(final GL2ES2 gl)
Removes all given shapes and destroys them, convenient call for removeAllShapes(GL2ES2,...
int getWidth()
Returns the getViewport()'s width, set after initial reshape(GLAutoDrawable, int, int,...
void setActiveTopLevelZOffsetScale(final float v)
Sets the general top-level widget Z-Offset scale, defaults to DEFAULT_ACTIVE_TOPLEVEL_ZOFFSET_SCALE.
void removeShapes(final Collection<? extends Shape > shapes)
Removes all given shapes, w/o Shape#destroy(GL2ES2, RegionRenderer).
final float[] getClearColor()
Returns the glClearColor(..) arguments, see setClearParams(float[], int).
void releaseActiveShape()
void addGLEventListener(final GLEventListener listener)
PMVMatrix4f getMatrix()
Borrow the current PMVMatrix4f.
List< Shape > getRenderedShapes()
Returns added shapes which are rendered and sorted by z-axis in ascending order toward z-near.
static final float DEFAULT_Z16_EPSILON
Default Z precision on 16-bit depth buffer using DEFAULT_SCENE_DIST z-position and DEFAULT_ZNEAR.
void pickShapeGL(final int glWinX, final int glWinY, final Vec3f objPos, final Shape[] shape, final Runnable runnable)
Attempt to pick a Shape using the OpenGL false color rendering.
static float getZEpsilon(final int zBits, final PMVMatrixSetup setup)
Default Z precision on 16-bit depth buffer using -1 z-position and DEFAULT_ZNEAR.
static final float DEFAULT_ANGLE
Default projection angle in radians is PI/4, i.e.
Shape getShapeByName(final String name)
void surfaceToPlaneSize(final Recti viewport, final float zNear, final float zFar, final float objOrthoDist, final Vec2f objSceneSize)
Map given window surface-size to object coordinates relative to this scene using the give projection ...
AABBox getBounds(final PMVMatrix4f pmv, final Shape shape)
Returns AABBox dimension of given Shape from this container's perspective, i.e.
final Shape getActiveShape()
int getHeight()
Returns the getViewport()'s height, set after initial reshape(GLAutoDrawable, int,...
synchronized void attachInputListenerTo(final GLWindow window)
Recti getViewport()
Borrows the current int[4] viewport w/o copying.
final boolean isCullingEnabled()
Return whether Project-Modelview (PMv) frustum culling or Group's Modelview (Mv) frustum clipping is ...
boolean removeShape(final GL2ES2 gl, final RegionRenderer renderer, final Shape s)
Removes given shape with Shape#destroy(GL2ES2, RegionRenderer), if contained.
synchronized void detachGLAutoDrawable(final GLAutoDrawable drawable)
boolean removeShape(final GL2ES2 gl, final Shape s)
Removes given shape and destroy it, if contained - convenient call for removeShape(GL2ES2,...
void removeShapes(final GL2ES2 gl, final Collection<? extends Shape > shapes)
Removes all given shapes and destroys them, convenient call for removeShape(GL2ES2,...
boolean invoke(final boolean wait, final GLRunnable glRunnable)
Enqueues a one-shot GLRunnable, which will be executed within the next GLAutoDrawable#display() call ...
boolean isOutside2(final Matrix4f mvCont, final Shape shape, final PMVMatrix4f pmvShape)
Returns whether the given Shape is completely outside of this container.
Shape getShapeByIdx(final int id)
static final float DEFAULT_ZNEAR
Default projection z-near value is {@value}.
int getScreenshotCount()
Return the number of nextScreenshotFile(String, String, int, GLCapabilitiesImmutable,...
void winToShapeCoord(final Shape shape, final int glWinX, final int glWinY, final PMVMatrix4f pmv, final Vec3f objPos, final Runnable runnable)
Calling Shape#winToObjCoord(Scene, int, int, float[]), retrieving its Shape object position.
Shape pickShape(final PMVMatrix4f pmv, final Ray ray, final int glWinX, final int glWinY, final Vec3f objPos, final Shape.Visitor1 visitor)
Attempt to pick a Shape using the window coordinates and contained {@ling Shape}'s AABBox bounds usin...
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height)
Reshape scene using setupMatrix(PMVMatrix4f, int, int, int, int) using PMVMatrixSetup.
void setSharpness(final float sharpness)
final int getClearMask()
Returns the glClear(..) mask, see setClearParams(float[], int).
int getAAQuality()
Returns RegionRenderer#getAAQuality().
final boolean isPMvCullingEnabled()
Return whether Project-Modelview (PMv) frustum culling is enabled for this container.
void addShapes(final Collection<? extends Shape > shapes)
String getStatusText(final GLAutoDrawable glad, final int renderModes, final float dpi)
Return a formatted status string containing avg fps and avg frame duration.
File nextScreenshotFile(final String dir, final String prefix, final int renderModes, final GLCapabilitiesImmutable caps, final String contentDetail)
Return the unique next technical screenshot PNG File instance as follows:
void setActiveShapeZOffsetScale(final float v)
Sets the active Shape Z-Offset scale, defaults to DEFAULT_ACTIVE_ZOFFSET_SCALE.
void removeGLEventListener(final GLEventListener listener)
int getShapeCount()
Returns number of Shapes, see getShapes().
static String getStatusText(final FPSCounter fpsCounter)
Return a formatted status string containing avg fps and avg frame duration.
void surfaceToPlaneSize(final Recti viewport, final Vec2f objSceneSize)
Map given window surface-size to object coordinates relative to this scene using the default PMVMatri...
void screenshot(final boolean wait, final File file)
Write current read drawable (screen) to a file on on the display call.
Generic Shape, potentially using a Graph via GraphShape or other means of representing content.
void draw(final GL2ES2 gl, final RegionRenderer renderer)
Renders the shape.
final Shape setDiscarded(final boolean v)
Set whether this shape is discarded in last draw(GL2ES2, RegionRenderer), i.e.
final Vec3f winToShapeCoord(final PMVMatrix4f pmv, final Recti viewport, final int glWinX, final int glWinY, final Vec3f objPos)
Map given gl-window-coordinates to object coordinates relative to this shape and its z-coordinate.
final void clear(final GL2ES2 gl, final RegionRenderer renderer)
Clears all data and reset all states as if this instance was newly created.
final void markStateDirty()
Marks the rendering state dirty, causing next draw() to notify the Graph region to reselect shader an...
static Comparator< Shape > ZAscendingComparator
final AABBox getBounds()
Returns the unscaled bounding AABBox for this shape, borrowing internal instance.
final boolean isVisible()
Returns true if this shape is set visible by the user, otherwise false.
void drawToSelect(final GL2ES2 gl, final RegionRenderer renderer)
Experimental selection draw command used by Scene.
final void markShapeDirty()
Marks the shape dirty, causing next draw() to recreate the Graph shape and reset the region.
final void destroy(final GL2ES2 gl, final RegionRenderer renderer)
Destroys all data.
final void applyMatToMv(final PMVMatrix4f pmv)
Applies the internal Matrix4f to the given modelview matrix, i.e.
final boolean isInteractive()
Returns if this shape allows user interaction in general, see setInteractive(boolean).
final boolean setActive(final boolean v, final float zOffset)
Basic Float math utility functions.
static float getOrthoWinZ(final float orthoZ, final float zNear, final float zFar)
Returns orthogonal distance (1f/zNear-1f/orthoZ) / (1f/zNear-1f/zFar);.
static float getZBufferEpsilon(final int zBits, final float z, final float zNear)
Returns resolution of Z buffer of given parameter, see Love Your Z-Buffer.
static final float QUARTER_PI
The value PI/4, i.e.
Basic 4x4 float matrix implementation using fields for intensive use-cases (host operations).
Simple compound denoting a ray.
Rectangle with x, y, width and height integer components.
2D Vector based upon two float components.
void set(final Vec2f o)
this = o, returns this.
3D Vector based upon three float components.
Axis Aligned Bounding Box.
final AABBox setSize(final float[] low, final float[] high)
Set size of the AABBox specifying the coordinates of the low and high.
final boolean isOutside(final AABBox box)
Returns whether the given AABBox is completely outside of this frustum.
PMVMatrix4f implements the basic computer graphics Matrix4f pack using projection (P),...
final boolean mapWinToRay(final float winx, final float winy, final float winz0, final float winz1, final Recti viewport, final Ray ray)
Map two window coordinates w/ shared X/Y and distinctive Z to a Ray.
final Matrix4f getMv()
Returns the modelview matrix (Mv).
final Frustum getFrustum()
Returns the frustum, derived from projection x modelview.
final PMVMatrix4f popMv()
Pop the modelview matrix from its stack.
final boolean mapWinToObj(final float winx, final float winy, final float winz, final Recti viewport, final Vec3f objPos)
Map window coordinates to object coordinates.
final PMVMatrix4f pushMv()
Push the modelview matrix to its stack, while preserving its values.
boolean isWithinGesture()
Returns true if within a gesture as detected by a previous process(InputEvent) command,...
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
final void removeGestureListener(final GestureHandler.GestureListener gl)
Removes the given GestureHandler.GestureListener from the list.
final void addGestureHandler(final GestureHandler gh)
Appends the given GestureHandler to the end of the list.
final void addMouseListener(final MouseListener l)
Appends the given MouseListener to the end of the list.
final void addGestureListener(final GestureHandler.GestureListener gl)
Appends the given GestureHandler.GestureListener to the end of the list.
final void addKeyListener(final KeyListener l)
Appends the given com.jogamp.newt.event.KeyListener to the end of the list.
final void removeKeyListener(final KeyListener l)
final void removeMouseListener(final MouseListener l)
Removes the given MouseListener from the list.
final void removeGestureHandler(final GestureHandler gh)
Removes the given GestureHandler from the list.
Utility to read out the current FB to TextureData, optionally writing the data back to a texture obje...
void write(final File dest)
Write the TextureData filled by readPixels(GLAutoDrawable, boolean) to file.
void dispose(final GL gl)
boolean readPixels(final GL gl, final boolean mustFlipVertically)
Read the drawable's pixels to TextureData and Texture, if requested at construction.
Container interface of UI Shapes.
Interface providing a method to setup PMVMatrix4f's GLMatrixFunc#GL_PROJECTION and GLMatrixFunc#GL_MO...
float getSceneDist()
Returns scene distance on z-axis to projection.
float getZFar()
Returns projection z-far value.
void set(PMVMatrix4f pmv, Recti viewport)
Setup PMVMatrix4f's GLMatrixFunc#GL_PROJECTION and GLMatrixFunc#GL_MODELVIEW.
void setPlaneBox(final AABBox planeBox, final PMVMatrix4f pmv, Recti viewport)
Optional method to set the Scene#getBounds() AABBox, maybe a nop if not desired.
float getZNear()
Returns projection z-near value.
float getAngle()
Returns fov projection angle in radians, shall be 0 for orthogonal projection.
int getAlphaBits()
Returns the number of bits for the color buffer's alpha component.
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
boolean invoke(boolean wait, GLRunnable glRunnable)
Enqueues a one-shot GLRunnable, which will be executed within the next display() call after all regis...
GLAnimatorControl getAnimator()
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
GLEventListener removeGLEventListener(GLEventListener listener)
Removes the given listener from this drawable queue.
GL getGL()
Casts this object to the GL interface.
GL2ES2 getGL2ES2()
Casts this object to the GL2ES2 interface.
int getSwapInterval()
Return the current swap interval.
Specifies an immutable set of OpenGL capabilities.
int getNumSamples()
Returns the number of sample buffers to be allocated if sample buffers are enabled,...
GLCapabilitiesImmutable getChosenGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the chosen OpenGL capabilities (pixel format / v...
NativeSurface getNativeSurface()
Returns the associated NativeSurface of this NativeSurfaceHolder.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.
static final int GL_COLOR_BUFFER_BIT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_COLOR_BUFFER_BIT" wit...
void glClearColor(float red, float green, float blue, float alpha)
Entry point to C language function: void {@native glClearColor}(GLfloat red, GLfloat green,...
void glClear(int mask)
Entry point to C language function: void {@native glClear}(GLbitfield mask) Part of GL_ES_VERSION_...
static final int GL_DEPTH_BUFFER_BIT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_DEPTH_BUFFER_BIT" wit...