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.graph.curve.Region;
53import com.jogamp.graph.curve.opengl.GLRegion;
54import com.jogamp.graph.curve.opengl.RegionRenderer;
55import com.jogamp.graph.curve.opengl.RenderState;
56import com.jogamp.math.FloatUtil;
57import com.jogamp.math.Matrix4f;
58import com.jogamp.math.Ray;
59import com.jogamp.math.Recti;
60import com.jogamp.math.Vec2f;
61import com.jogamp.math.Vec3f;
62import com.jogamp.math.geom.AABBox;
63import com.jogamp.math.util.PMVMatrix4f;
64import com.jogamp.newt.event.GestureHandler;
65import com.jogamp.newt.event.InputEvent;
66import com.jogamp.newt.event.KeyEvent;
67import com.jogamp.newt.event.KeyListener;
68import com.jogamp.newt.event.MouseEvent;
69import com.jogamp.newt.event.MouseListener;
70import com.jogamp.newt.event.PinchToZoomGesture;
71import com.jogamp.newt.event.GestureHandler.GestureEvent;
72import com.jogamp.newt.opengl.GLWindow;
73import com.jogamp.opengl.util.GLPixelStorageModes;
74import com.jogamp.opengl.util.GLReadBufferUtil;
75import com.jogamp.opengl.util.texture.TextureSequence;
77import jogamp.graph.ui.TreeTool;
130 private static final boolean DEBUG =
false;
131 private static final boolean DEBUG_PICKING = DEBUG;
133 private final List<Shape> shapes =
new CopyOnWriteArrayList<Shape>();
134 private Shape[] displayShapeArray =
new Shape[0];
135 private final List<Shape> renderedShapesB0 =
new ArrayList<Shape>();
136 private final List<Shape> renderedShapesB1 =
new ArrayList<Shape>();
137 private final List<Shape> renderedShapesB2 =
new ArrayList<Shape>();
138 private volatile List<Shape> renderedShapes = renderedShapesB1;
139 private int renderedShapesIdx = 1;
140 private final AtomicReference<Tooltip> toolTipActive =
new AtomicReference<Tooltip>();
141 private final AtomicReference<Shape> toolTipHUD =
new AtomicReference<Shape>();
142 private final List<Group> topLevel =
new ArrayList<Group>();
144 private boolean doFrustumCulling =
false;
146 private float[] clearColor =
null;
147 private int clearMask;
152 private final AABBox planeBox =
new AABBox(0f, 0f, 0f, 0f, 0f, 0f);
154 private volatile Shape activeShape =
null;
155 private volatile Group activeTopLevel =
null;
157 private SBCMouseListener sbcMouseListener =
null;
158 private SBCGestureListener sbcGestureListener =
null;
160 private SBCKeyListener sbcKeyListener =
null;
177 this( createRenderer() );
188 public Scene(
final int sampleCount) {
189 this( createRenderer() );
200 if(
null == renderer ) {
201 throw new IllegalArgumentException(
"Null RegionRenderer");
203 this.renderer = renderer;
221 public final void setClearParams(
final float[] clearColor,
final int clearMask) { this.clearColor = clearColor; this.clearMask = clearMask; }
239 cDrawable = drawable;
242 if( cDrawable == drawable ) {
248 if(
null == sbcMouseListener) {
249 sbcMouseListener =
new SBCMouseListener();
251 sbcGestureListener =
new SBCGestureListener();
256 if(
null == sbcKeyListener) {
257 sbcKeyListener =
new SBCKeyListener();
263 if(
null != sbcMouseListener) {
265 sbcMouseListener =
null;
267 sbcGestureListener =
null;
269 pinchToZoomGesture =
null;
271 if(
null == sbcKeyListener) {
273 sbcKeyListener =
null;
293 if( shapes.remove(s) ) {
302 for(
final Shape s : shapes) {
309 if( shapes.remove(s) ) {
322 public void addShapes(
final Collection<? extends Shape> shapes) {
323 for(
final Shape s : shapes) {
329 for(
final Shape s : shapes) {
339 final int count = shapes.size();
340 for(
int i=count-1; i>=0; --i) {
351 return TreeTool.contains(
this, s);
358 return shapes.get(
id);
362 return TreeTool.getShapeByID(
this,
id);
366 return TreeTool.getShapeByName(
this, name);
386 TreeTool.forAll(
this, (
final Shape s) -> {
394 TreeTool.forAll(
this, (
final Shape s) -> {
400 TreeTool.forAll(
this, (
final Shape s) -> {
408 if(
null == cDrawable ) {
409 cDrawable = drawable;
428 public boolean invoke(
final boolean wait,
final GLRunnable glRunnable)
throws IllegalStateException {
429 if(
null != cDrawable ) {
430 return cDrawable.
invoke(wait, glRunnable);
436 if(
null != cDrawable ) {
441 if(
null != cDrawable ) {
467 if( doFrustumCulling ){
479 if( doFrustumCulling ){
488 final int shapeCount = shapes.size();
489 Arrays.fill(displayShapeArray,
null);
490 final Shape[] shapeArray = shapes.toArray(displayShapeArray);
491 displayShapeArray = shapeArray;
498 final List<Shape> iShapes;
500 switch(renderedShapesIdx) {
501 case 0: iShapeIdx = 1; iShapes = renderedShapesB1;
break;
502 case 1: iShapeIdx = 2; iShapes = renderedShapesB2;
break;
503 default: iShapeIdx = 0; iShapes = renderedShapesB0;
break;
505 if(
null != clearColor ) {
506 gl.
glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
509 renderer.
enable(gl,
true);
511 synchronized( iShapes ) {
514 for(
int i=0; i<shapeCount; i++) {
515 final Shape shape = shapeArray[i];
521 shape.
draw(gl, renderer);
532 renderer.
enable(gl,
false);
533 renderedShapes = iShapes;
534 renderedShapesIdx = iShapeIdx;
536 synchronized ( syncDisplayedOnce ) {
537 displayedOnce =
true;
538 syncDisplayedOnce.notifyAll();
540 final Tooltip tt = toolTipActive.get();
542 activateTooltipImpl(drawable, pmv, tt);
546 private void displayGLSelect(
final GLAutoDrawable drawable,
final Object[] shapes) {
556 final int shapeCount = shapes.length;
557 for(
int i=0; i<shapeCount; i++) {
564 final float color = ( i + 1f ) / ( shapeCount + 2f );
573 renderer.
enable(gl,
false, RegionRenderer.defaultBlendDisable, RegionRenderer.defaultBlendDisable);
574 synchronized ( syncDisplayedOnce ) {
575 displayedOnce =
true;
576 syncDisplayedOnce.notifyAll();
580 private volatile boolean displayedOnce =
false;
581 private final Object syncDisplayedOnce =
new Object();
585 synchronized( syncDisplayedOnce ) {
586 while( !displayedOnce ) {
588 syncDisplayedOnce.wait();
589 }
catch (
final InterruptedException e) { }
606 synchronized ( syncDisplayedOnce ) {
607 displayedOnce =
false;
608 syncDisplayedOnce.notifyAll();
610 if( drawable instanceof
GLWindow ) {
615 for(
int i=0; i<shapes.size(); i++) {
616 shapes.get(i).destroy(gl, renderer);
618 for(
int i=0; i<disposeActions.size(); i++) {
620 disposeActions.get(i).run(drawable);
621 }
catch(
final Throwable t) {
622 System.err.println(
"Scene.dispose: Caught Exception @ User Disposable["+i+
"]: "+t.getMessage());
628 displayShapeArray =
new Shape[0];
629 renderedShapesB0.
clear();
630 renderedShapesB1.clear();
631 renderedShapesB2.clear();
632 renderedShapes = renderedShapesB1;
633 renderedShapesIdx = 1;
634 disposeActions.clear();
635 if( drawable == cDrawable ) {
641 private final List<GLRunnable> disposeActions =
new ArrayList<GLRunnable>();
663 if(
null == shape ) {
668 TreeTool.forOne(
this, pmv, shape, () -> {
669 if(
null != shape.
winToShapeCoord(pmv, viewport, glWinX, glWinY, objPos) ) {
678 if(
null == shape ) {
682 TreeTool.forOne(
this, pmv, shape, () -> {
754 pmvMatrixSetup.
set(pmv, viewport);
820 final float zNear,
final float zFar,
821 final float winX,
final float winY,
final float objOrthoZ,
822 final Vec3f objPos) {
824 pmv.
mapWinToObj(winX, winY, winZ, viewport, objPos);
845 objSceneSize.
set( obj11Coord.x() - obj00Coord.x(),
846 obj11Coord.y() - obj00Coord.y() );
865 final Shape lastShape = activeShape;
866 if(
null != lastShape ) {
867 final Group lastTL = activeTopLevel;
871 activeTopLevel =
null;
872 if(
null != lastTL ) {
873 lastTL.setActiveTopLevel(
false, 0);
875 if( DEBUG_PICKING ) {
876 System.err.println(
"ACTIVE-RELEASE: s 0x"+Integer.toHexString(System.identityHashCode(lastShape))+
", "+lastShape);
877 System.err.println(
"ACTIVE-RELEASE: g 0x"+Integer.toHexString(System.identityHashCode(lastTL))+
", "+lastTL);
878 dumpTopLevelParent();
882 private void setActiveShape(
final Shape shape) {
883 final Shape lastShape = activeShape;
884 if( lastShape != shape &&
null != shape ) {
886 final boolean isTopLevel = topLevel.contains(shape);
887 final float newZOffset = ( isTopLevel ? activeZOffsetScale : activeTopLevelZOffsetScale ) * zEpsilon;
888 if( shape.
setActive(
true, newZOffset) ) {
889 final Group lastTL = activeTopLevel;
890 final Group thisTL = isTopLevel ? (
Group)shape : getTopLevelParent(shape);
892 if(
null != lastShape && thisTL != lastShape ) {
896 if( lastTL != thisTL ) {
899 lastTL.setActiveTopLevel(
false, 0);
902 if(
null!=thisTL && !isTopLevel ) {
903 thisTL.setActiveTopLevel(
true, activeTopLevelZOffsetScale * zEpsilon);
906 activeTopLevel = thisTL;
909 if( DEBUG_PICKING ) {
910 System.err.println(
"ACTIVE-SHAPE: NEW mode "+mode+
", isTopLevel "+isTopLevel+
", s 0x"+Integer.toHexString(System.identityHashCode(shape))+
", "+shape);
911 System.err.println(
"ACTIVE-SHAPE: NEW g 0x"+Integer.toHexString(System.identityHashCode(thisTL))+
", "+thisTL);
912 System.err.println(
"ACTIVE-SHAPE: PRE s 0x"+Integer.toHexString(System.identityHashCode(lastShape))+
", "+lastShape);
913 System.err.println(
"ACTIVE-SHAPE: PRE g 0x"+Integer.toHexString(System.identityHashCode(lastTL))+
", "+lastTL);
934 void addTopLevel(
final Group g) { topLevel.add(g); }
935 void removeTopLevel(
final Group g) { topLevel.add(g); }
936 private Group getTopLevelParent(
final Shape s) {
937 for(
final Group g : topLevel) {
944 private void dumpTopLevelParent() {
946 for(
final Group g : topLevel) {
947 final boolean a0 = g.isActive();
948 System.err.printf(
"- %02d: 0x%08x %s %s/%s, %s%n", idx++, System.identityHashCode(g), (a0?
"****":
"____"), g.getClass().getSimpleName(), g.getName(), g);
950 final int idx1 = idx-1;
951 final int[] idx2 = { 0 };
952 TreeTool.forAll(g, (
final Shape s) -> {
953 final boolean a1 = s.isActive();
954 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);
961 private final class SBCGestureListener
implements GestureHandler.GestureListener {
963 public void gestureDetected(
final GestureEvent gh) {
965 if(
null != activeShape ) {
967 final InputEvent orig = gh.getTrigger();
968 if( orig instanceof MouseEvent ) {
969 final Shape shape = activeShape;
970 if( shape.isInteractive() ) {
971 final MouseEvent e = (MouseEvent) orig;
973 final int glWinX = e.getX();
974 final int glWinY =
getHeight() - e.getY() - 1;
975 final PMVMatrix4f pmv =
new PMVMatrix4f();
976 final Vec3f objPos =
new Vec3f();
978 shape.dispatchGestureEvent(gh, glWinX, glWinY, pmv, renderer.
getViewport(), objPos);
1000 public void pickShapeGL(
final int glWinX,
final int glWinY,
final Vec3f objPos,
final Shape[] shape,
final Runnable runnable) {
1001 if(
null == cDrawable ) {
1007 final Shape s = pickShapeGLImpl(drawable, glWinX, glWinY);
1022 @SuppressWarnings({
"unchecked",
"rawtypes" })
1023 private Shape pickShapeGLImpl(
final GLAutoDrawable drawable,
final int glWinX,
final int glWinY) {
1024 final Object[] shapesS = shapes.toArray();
1025 Arrays.sort(shapesS, (Comparator)Shape.ZAscendingComparator);
1027 final GLPixelStorageModes psm =
new GLPixelStorageModes();
1028 final ByteBuffer pixel = Buffers.newDirectByteBuffer(4);
1032 displayGLSelect(drawable, shapesS);
1034 psm.setPackAlignment(gl, 4);
1038 gl.glReadPixels(glWinX, glWinY, 1, 1, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixel);
1039 }
catch(
final GLException gle) {
1040 gle.printStackTrace();
1046 final int shapeCount = shapes.size();
1047 final int qp = pixel.get(0) & 0xFF;
1048 final float color = qp / 255.0f;
1049 final int index = Math.round( ( color * ( shapeCount + 2f) ) - 1f );
1052 System.err.printf(
"pickGL: glWin %d / %d, byte %d, color %f, index %d of [0..%d[%n",
1053 glWinX, glWinY, qp, color, index, shapeCount);
1055 if( 0 <= index && index < shapeCount ) {
1056 return (Shape)shapesS[index];
1065 private static interface PickVisitor {
1072 Shape visit(Shape s,
final PMVMatrix4f pmv);
1074 private static Shape pickForAllRenderedDesc(
final Container cont,
final PMVMatrix4f pmv,
final PickVisitor v) {
1075 Shape picked =
null;
1076 final List<Shape> shapes = cont.getRenderedShapes();
1077 synchronized( shapes ) {
1078 for(
int i=shapes.size()-1;
null == picked && i>=0; --i) {
1079 final Shape s = shapes.get(i);
1081 s.applyMatToMv(pmv);
1082 picked = v.visit(s, pmv);
1083 if( s instanceof Container ) {
1084 final Shape childPick = pickForAllRenderedDesc((Container)s, pmv, v);
1085 if(
null != childPick ) {
1116 final float winZ0 = 0f;
1117 final float winZ1 = 0.3f;
1124 final int[] shapeIdx = { -1 };
1125 return pickForAllRenderedDesc(
this, pmv, (
final Shape s,
final PMVMatrix4f pmv2) -> {
1127 if( pmv.
mapWinToRay(glWinX, glWinY, winZ0, winZ1, viewport, ray) ) {
1128 final AABBox sbox = s.getBounds();
1129 if( sbox.intersectsRay(ray) ) {
1130 if( null == sbox.getRayIntersection(objPos, ray, FloatUtil.EPSILON, true) ) {
1131 throw new InternalError(
"Ray "+ray+
", box "+sbox);
1133 if( visitor.visit(s) ) {
1147 private final Shape dispatchMouseEventPickShape(
final MouseEvent e,
final int glWinX,
final int glWinY) {
1148 final Shape shape = pickShape(dispMEPSPMv, dispMEPSRay, glWinX, glWinY, dispMEPSObjPos, (
final Shape s) -> {
1150 if( !s.isInteractive() ) {
1151 if( DEBUG_PICKING ) {
1152 System.err.printf(
"Pick.X.0: shape %s/%s, [%d, %d]%n", s.getClass().getSimpleName(), s.getName(), glWinX, glWinY);
1156 if( !s.dispatchMouseEvent(e, glWinX, glWinY, dispMEPSObjPos) ) {
1157 if( DEBUG_PICKING ) {
1158 System.err.printf(
"Pick.X.1: shape %s/%s, [%d, %d], %s%n", s.getClass().getSimpleName(), s.getName(), glWinX, glWinY, e);
1162 if( DEBUG_PICKING ) {
1163 System.err.printf(
"Pick.X.S: shape %s/%s, [%d, %d], %s%n", s.getClass().getSimpleName(), s.getName(), glWinX, glWinY, e);
1167 if(
null != shape ) {
1168 if( DEBUG_PICKING ) {
1169 System.err.printf(
"Pick.X: shape %s/%s%n%n", shape.getClass().getSimpleName(), shape.getName());
1171 setActiveShape(shape);
1174 if( DEBUG_PICKING ) {
1175 System.err.printf(
"Pick.X: shape null%n%n");
1177 releaseActiveShape();
1181 private final PMVMatrix4f dispMEPSPMv =
new PMVMatrix4f();
1182 private final Ray dispMEPSRay =
new Ray();
1183 private final Vec3f dispMEPSObjPos =
new Vec3f();
1192 private final void dispatchMouseEventForShape(
final Shape shape,
final MouseEvent e,
final int glWinX,
final int glWinY) {
1193 final PMVMatrix4f pmv =
new PMVMatrix4f();
1194 final Vec3f objPos =
new Vec3f();
1195 winToShapeCoord(shape, glWinX, glWinY, pmv, objPos, () -> { shape.dispatchMouseEvent(e, glWinX, glWinY, objPos); });
1196 if( DEBUG_PICKING ) {
1197 System.err.printf(
"ForShape: shape %s/%s%n%n", shape.getClass().getSimpleName(), shape.getName());
1201 private final class SBCMouseListener
implements MouseListener {
1202 private int lx, ly, lId;
1203 private boolean mouseOver;
1205 private SBCMouseListener() {
1208 private final void clear() {
1209 lx = -1; ly = -1; lId = -1; mouseOver =
false;
1211 private final Shape dispatchPickShape(
final MouseEvent e,
final int glWinX,
final int glWinY) {
1212 final Shape s = dispatchMouseEventPickShape(e, glWinX, glWinY);
1219 public void mousePressed(
final MouseEvent e) {
1220 if( -1 == lId || e.getPointerId(0) == lId ) {
1223 lId = e.getPointerId(0);
1226 final int glWinX = e.getX();
1227 final int glWinY = getHeight() - e.getY() - 1;
1231 dispatchPickShape(e, glWinX, glWinY);
1235 public void mouseReleased(
final MouseEvent e) {
1237 final int glWinX = e.getX();
1238 final int glWinY = getHeight() - e.getY() - 1;
1239 if( mouseOver &&
null != activeShape && activeShape.
isInteractive() && !pinchToZoomGesture.
isWithinGesture() && e.getPointerId(0) == lId ) {
1240 dispatchMouseEventForShape(activeShape, e, glWinX, glWinY);
1242 dispatchPickShape(e, glWinX, glWinY);
1244 if( !mouseOver && 1 == e.getPointerCount() ) {
1246 releaseActiveShape();
1252 public void mouseClicked(
final MouseEvent e) {
1254 final int glWinX = e.getX();
1255 final int glWinY = getHeight() - e.getY() - 1;
1259 dispatchPickShape(e, glWinX, glWinY);
1263 public void mouseDragged(
final MouseEvent e) {
1272 final int glWinX = e.getX();
1273 final int glWinY = getHeight() - e.getY() - 1;
1274 dispatchMouseEventForShape(activeShape, e, glWinX, glWinY);
1279 public void mouseWheelMoved(
final MouseEvent e) {
1282 final int glWinX = lx;
1283 final int glWinY = getHeight() - ly - 1;
1284 if( mouseOver &&
null != activeShape && activeShape.
isInteractive() && !pinchToZoomGesture.
isWithinGesture() && e.getPointerId(0) == lId ) {
1285 dispatchMouseEventForShape(activeShape, e, glWinX, glWinY);
1287 dispatchPickShape(e, glWinX, glWinY);
1292 public void mouseMoved(
final MouseEvent e) {
1293 if( -1 == lId || e.getPointerId(0) == lId ) {
1296 lId = e.getPointerId(0);
1299 final int glWinX = lx;
1300 final int glWinY = getHeight() - ly - 1;
1301 final Shape s = dispatchPickShape(e, glWinX, glWinY);
1304 synchronized( toolTipActive ) {
1305 toolTipActive.set( s.startToolTip(
true ) );
1310 public void mouseEntered(
final MouseEvent e) { }
1312 public void mouseExited(
final MouseEvent e) {
1314 releaseActiveShape();
1318 private final class SBCKeyListener
implements KeyListener {
1320 public void keyPressed(
final KeyEvent e) {
1322 activeShape.dispatchKeyEvent(e);
1327 public void keyReleased(
final KeyEvent e) {
1329 activeShape.dispatchKeyEvent(e);
1334 private void setToolTip(
final Shape hud) {
1336 toolTipHUD.set( hud );
1339 private void clearToolTip() {
1341 synchronized( toolTipActive ) {
1342 tt = toolTipActive.get();
1343 if(
null != tt && tt.stop(
false) ) {
1344 toolTipActive.set(
null);
1347 final Shape s = toolTipHUD.getAndSet(
null);
1349 invoke(
false, (
final GLAutoDrawable drawable) -> {
1351 if( s == removeShape(s) ) {
1352 tt.destroyTip(drawable.getGL().getGL2ES2(), renderer, s);
1355 removeShape(drawable.getGL().getGL2ES2(), renderer, s);
1361 private void activateTooltipImpl(
final GLAutoDrawable drawable,
final PMVMatrix4f pmv,
final Tooltip tt) {
1362 if(
null == toolTipHUD.get() ) {
1363 final Shape[] hud = {
null };
1364 if( tt.tick() && TreeTool.forOne(
this, pmv, tt.getTool(), () -> {
1365 final AABBox toolMvBounds = tt.getToolMvBounds(pmv);
1366 hud[0] = tt.createTip(Scene.this, toolMvBounds);
1369 setToolTip( hud[0] );
1383 final float lfps, tfps, td;
1384 if(
null != fpsCounter ) {
1395 final String blendStr;
1397 blendStr =
", blend";
1401 return String.format(
"%03.1f/%03.1f fps, %.1f ms/f, vsync %d, dpi %.1f, %s%s, a %d",
1414 return String.format(
"%03.1f/%03.1f fps, %.1f ms/f", lfps, tfps, td);
1435 final String dir2 = (
null != dir && dir.length() > 0 ) ? dir :
"";
1436 final String prefix2 = (
null != prefix && prefix.length() > 0 ) ? prefix+
"-" :
"";
1439 final String contentDetail2 = (
null != contentDetail && contentDetail.length() > 0 ) ? contentDetail+
"-" :
"";
1440 return new File( String.format((Locale)
null,
"%s%s%s-%ssnap%02d-%04dx%04d.png",
1441 dir2, prefix2, modeS, contentDetail2,
1444 private int screenShotCount = 0;
1463 screenshot.
write(file);
1464 System.err.println(
"Wrote: "+file);
1478 if(
null != cDrawable ) {
1479 cDrawable.
invoke(wait, (drawable) -> {
1480 screenshot(drawable.getGL(), file);
1508 private final float scene_dist;
1510 private final float angle;
1512 private final float zNear;
1514 private final float zFar;
1527 if( !( zNear > 0 && zFar > zNear ) ) {
1528 throw new IllegalArgumentException(
"zNear is "+zNear+
", but must be > 0 and < zFar, zFar "+zFar);
1530 this.scene_dist = scene_dist;
1569 final float ratio = (float) viewport.width() / (float) viewport.height();
1570 pmv.loadPIdentity();
1571 pmv.perspectiveP(angle, ratio, zNear, zFar);
1572 pmv.translateP(0f, 0f, scene_dist);
1574 pmv.loadMvIdentity();
1579 final float orthoDist = -scene_dist;
1583 winToPlaneCoord(pmv, viewport, zNear, zFar, viewport.x(), viewport.y(), orthoDist, obj00Coord);
1584 winToPlaneCoord(pmv, viewport, zNear, zFar, viewport.width(), viewport.height(), orthoDist, obj11Coord);
1586 planeBox.
setSize( obj00Coord, obj11Coord );
1598 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).
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...