diff options
3 files changed, 54 insertions, 51 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java index 20ecdb65d..fafd157ca 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java @@ -58,6 +58,7 @@ import com.jogamp.graph.ui.widgets.RangeSlider; import com.jogamp.graph.ui.widgets.RangedGroup; import com.jogamp.graph.ui.widgets.RangedGroup.SliderParam; import com.jogamp.math.Vec2f; +import com.jogamp.math.Vec3f; import com.jogamp.math.geom.AABBox; import com.jogamp.newt.event.KeyAdapter; import com.jogamp.newt.event.KeyEvent; @@ -272,21 +273,26 @@ public class FontView01 { System.err.println("GlyphGrid "+glyphGrid); System.err.println("GlyphGrid "+glyphGrid.getLayout()); } - final RangedGroup glyphView = new RangedGroup(options.renderModes, glyphGrid, glyphGridSize, + // culling >= 2*cell-size outside of clipping box (vertical only), pixel-accurate clipping in-between until clipping-box + final Vec3f clipCullingScale = new Vec3f(1f, 1f+2*glyphGridCellSize/glyphGridSize.y(), 1f); + // final Vec3f clipCullingScale = new Vec3f(1f, 1f, 1f); // no pixel-accurate clipping, just culling in Group + if( VERBOSE_UI ) { + System.err.println("RangedGroup clipCullingScale "+clipCullingScale); + } + final RangedGroup glyphView = new RangedGroup(options.renderModes, glyphGrid, glyphGridSize, clipCullingScale, null, new SliderParam(new Vec2f(glyphGridCellSize/4f, glyphGridSize.y()), glyphGridCellSize/10f, true)); glyphView.getVertSlider().setColor(0.3f, 0.3f, 0.3f, 0.7f); - glyphView.getVertSlider().addSliderListener(new SliderAdapter() { - @Override - public void dragged(final RangeSlider w, final float old_val, final float val, final float old_val_pct, final float val_pct) { - final Vec2f minmax = w.getMinMax(); - final float row_f = val / glyphGridCellSize; - if( VERBOSE_UI ) { + if( VERBOSE_UI ) { + glyphView.getVertSlider().addSliderListener(new SliderAdapter() { + @Override + public void dragged(final RangeSlider w, final float old_val, final float val, final float old_val_pct, final float val_pct) { + final Vec2f minmax = w.getMinMax(); + final float row_f = val / glyphGridCellSize; System.err.println("VertSlider: row "+row_f+", val["+old_val+" -> "+val+"], pct["+(100*old_val_pct)+"% -> "+(100*val_pct)+"%], minmax "+minmax); } - gridDim.setStartRow((int)row_f, glyphGrid); - } - }); + }); + } glyphGrid.setInteractive(true).setDragAndResizeable(false).setToggleable(false); glyphView.getVertSlider().receiveKeyEvents(glyphGrid); glyphView.getVertSlider().receiveMouseEvents(glyphGrid); @@ -364,7 +370,7 @@ public class FontView01 { final float nsPerGlyph = total / gridDim.glyphCount; System.err.println("PERF: Total took "+(total/1000000.0)+"ms, per-glyph "+(nsPerGlyph/1000000.0)+"ms, glyphs "+gridDim.glyphCount); } - printScreenOnGLThread(scene, window.getChosenGLCapabilities(), font, gridDim.contourChars.get(gridDim.rowStartIndex)); + printScreenOnGLThread(scene, window.getChosenGLCapabilities(), font, gridDim.contourChars.get(0)); // stay open .. } @@ -381,8 +387,6 @@ public class FontView01 { final int rows; final int rowsPerPage; final int elemCount; - int rowStartIndex; - int rowPos; int maxNameLen; public GridDim(final Font font, final int columns, final int rowsPerPage, final int xReserved) { @@ -393,8 +397,6 @@ public class FontView01 { this.rows = (int)Math.ceil((double)glyphCount / (double)columnsNet); this.rowsPerPage = rowsPerPage; this.elemCount = glyphCount + ( rows * xReserved ); - this.rowStartIndex = 0; - this.rowPos = 0; this.maxNameLen=10; } @@ -417,30 +419,8 @@ public class FontView01 { System.err.println("PERF: GlyphScan took "+(total/1000000.0)+"ms, per-glyph "+(nsPerGlyph/1000000.0)+"ms, glyphs "+contourChars.size()); return contourChars.size(); } - - float setStartRow(final int row, final Group glyphGrid) { - // GridDim[contours 6399, start 0, row 0, 18x356=6408<=6755, rows/pg 14] - // GridDim[contours 6399, start 0, row 0, 18x377=6786<=6776, rows/pg 14] - // final int old = start; - final int np = row * columns; - if( np < elemCount - columns ) { - rowStartIndex = np; - rowPos = row; - } - if( null != glyphGrid ) { - final int max = Math.min(elemCount, rowStartIndex + ( ( rowsPerPage + 1 ) * columns )); // one extra row - for(int idx = rowStartIndex; idx < max; ++idx) { - final Shape s = glyphGrid.getShapeByIdx(idx); - s.setVisible(true); - // System.err.println("Visible["+(startIdx + idx)+"].1: "+s); - } - } - // System.err.println("XXX "+columns+"x"+rows+" @ "+old+"/"+elemCount+": r "+row+" -> s "+start); - return rowStartIndex; - } - @Override - public String toString() { return "GridDim[contours "+glyphCount+", start "+rowStartIndex+", row "+rowPos+", "+columns+"x"+rows+"="+(columns*rows)+">="+elemCount+", rows/pg "+rowsPerPage+"]"; } + public String toString() { return "GridDim[contours "+glyphCount+", "+columns+"x"+rows+"="+(columns*rows)+">="+elemCount+", rows/pg "+rowsPerPage+"]"; } } static void addGlyphs(final GLProfile glp, final Font font, final Group sink, @@ -483,14 +463,13 @@ public class FontView01 { final float sxy = 1f/7f; // gridDim.maxNameLen; // 0.10f; // Math.min(sx, sy); c2.addShape( l.scale(sxy, sxy, 1).setColor(0, 0, 0, 1).setInteractive(false).setDragAndResizeable(false) ); } - sink.addShape(c2.setVisible(false)); + sink.addShape(c2); // System.err.println("Add.2: "+c2); } else { - sink.addShape(c1.setVisible(false)); + sink.addShape(c1); // System.err.println("Add.1: "+c1); } } - gridDim.setStartRow(0, sink); final long t1 = Clock.currentNanos(); final long total = t1 - t0; final float nsPerGlyph = total / gridDim.glyphCount; diff --git a/src/graphui/classes/com/jogamp/graph/ui/Group.java b/src/graphui/classes/com/jogamp/graph/ui/Group.java index fe561baa7..765bc229a 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/Group.java +++ b/src/graphui/classes/com/jogamp/graph/ui/Group.java @@ -126,14 +126,16 @@ public class Group extends Shape implements Container { /** * Enable {@link AABBox} clipping on {@link #getBounds()} for this group and its shapes as follows * <ul> - * <li>Discard {@link Shape} {@link #draw(GL2ES2, RegionRenderer, int[]) rendering} if completely outside of the {@code clip-box * cullingScale}.</li> - * <li>Otherwise perform pixel-accurate clipping inside the shader on {@code clip-box}.</li> + * <li>Discard {@link Shape} {@link #draw(GL2ES2, RegionRenderer, int[]) rendering} if completely outside of {@code clip-box*cullingScale}.</li> + * <li>Otherwise perform pixel-accurate clipping inside the shader within [{@code clip-box} .. {@code clip-box*cullingScale}].</li> + * <li>If {@code clip-box} >= {@code clip-box*cullingScale} for all axis, no pixel-accurate clipping is performed as shapes are culled before.</li> * </ul> * <p> * {@link #setClipBBox(AABBox)} takes precedence over {@link #setClipOnBounds(boolean)}. * </p> * @param v boolean to toggle clipping - * @param cullingScale culling scale factor per axis for the {@code clip-box} to discard {@link #draw(GL2ES2, RegionRenderer, int[]) rendering} completely. + * @param cullingScale culling scale factor per axis for the {@code clip-box} to discard {@link #draw(GL2ES2, RegionRenderer, int[]) rendering} completely, + * should be {@code >= 1} for each axis. * @return this instance for chaining * @see #setClipBBox(AABBox) */ @@ -144,14 +146,16 @@ public class Group extends Shape implements Container { /** * Enable {@link AABBox} clipping on explicit given pre-multiplied Mv-matrix {@code clip-box} as follows * <ul> - * <li>Discard {@link Shape} {@link #draw(GL2ES2, RegionRenderer, int[]) rendering} if completely outside of the {@code clip-box * cullingScale}.</li> - * <li>Otherwise perform pixel-accurate clipping inside the shader on {@code clip-box}.</li> + * <li>Discard {@link Shape} {@link #draw(GL2ES2, RegionRenderer, int[]) rendering} if completely outside of {@code clip-box*cullingScale}.</li> + * <li>Otherwise perform pixel-accurate clipping inside the shader within [{@code clip-box} .. {@code clip-box*cullingScale}].</li> + * <li>If {@code clip-box} >= {@code clip-box*cullingScale} for all axis, no pixel-accurate clipping is performed as shapes are culled before.</li> * </ul> * <p> * {@link #setClipBBox(AABBox)} takes precedence over {@link #setClipOnBounds(boolean)}. * </p> * @param v {@link AABBox} pre-multiplied Mv-matrix - * @param cullingScale culling scale factor per axis for the {@code clip-box} to discard {@link #draw(GL2ES2, RegionRenderer, int[]) rendering} completely. + * @param cullingScale culling scale factor per axis for the {@code clip-box} to discard {@link #draw(GL2ES2, RegionRenderer, int[]) rendering} completely, + * should be {@code >= 1} for each axis. * @return this instance for chaining * @see #setClipOnBounds(boolean) */ @@ -289,7 +293,9 @@ public class Group extends Shape implements Container { final AABBox origClipBox = renderer.getClipBBox(); final AABBox clipBox = useClipBBox ? clipBBox : box.transform(pmv.getMv(), tempBB0); - renderer.setClipBBox( tempBB1.set(clipBox) ); // Mv pre-multiplied AABBox + if( clipCullingScale.x() > 1f || clipCullingScale.y() > 1f || clipCullingScale.z() > 1f) { + renderer.setClipBBox( tempBB1.set(clipBox) ); // Mv pre-multiplied AABBox + } // else clip-box >= 'clip-box*cullingScale' for all axis, no pixel-accurate clipping is performed as shapes are culled before clipBox.scale(clipCullingScale.x(), clipCullingScale.y(), clipCullingScale.z()); final int shapeCount = shapesS.length; diff --git a/src/graphui/classes/com/jogamp/graph/ui/widgets/RangedGroup.java b/src/graphui/classes/com/jogamp/graph/ui/widgets/RangedGroup.java index 1f41e8a46..0f1a9d43a 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/widgets/RangedGroup.java +++ b/src/graphui/classes/com/jogamp/graph/ui/widgets/RangedGroup.java @@ -29,6 +29,7 @@ package com.jogamp.graph.ui.widgets; import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.GLRegion; +import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.ui.Group; import com.jogamp.graph.ui.Shape; import com.jogamp.graph.ui.layout.Alignment; @@ -36,6 +37,7 @@ import com.jogamp.graph.ui.layout.GridLayout; import com.jogamp.graph.ui.widgets.RangeSlider.SliderAdapter; import com.jogamp.math.Vec2f; import com.jogamp.math.Vec3f; +import com.jogamp.math.Vec4f; import com.jogamp.math.geom.AABBox; import com.jogamp.opengl.GL2ES2; import com.jogamp.opengl.GLProfile; @@ -48,6 +50,7 @@ import com.jogamp.opengl.util.texture.TextureSequence; public class RangedGroup extends Widget { private final Group content; private final Group clippedContent; + private final Vec3f clipCullingScale; private final RangeSlider horizSlider, vertSlider; private final Vec2f contentPosZero = new Vec2f(); @@ -82,10 +85,14 @@ public class RangedGroup extends Widget { * @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}. * @param content the {@link Group} with content to view * @param contentSize the fixed size of the clipped content to view, i.e. page-size + * @param cullingScale culling scale factor per axis for the {@code clip-box} to discard + * {@link #draw(GL2ES2, RegionRenderer, int[]) rendering} completely outside of {@code clip-box*cullingScale}. + * Pixel-accurate clipping is applied within [{@code clip-box} .. {@code clip-box*cullingScale}] if any scale-axis of {@code cullingScale} > 1. + * See {@link Group#setClipBBox(AABBox, Vec3f)}. * @param horizSliderParam optional horizontal slider parameters, null for none * @param vertSliderParam optional vertical slider parameters, null for none */ - public RangedGroup(final int renderModes, final Group content, final Vec2f contentSize, + public RangedGroup(final int renderModes, final Group content, final Vec2f contentSize, final Vec3f cullingScale, final SliderParam horizSliderParam, final SliderParam vertSliderParam) { super( new GridLayout(1 + (null != vertSliderParam ? 1 : 0), 0f, 0f, Alignment.None)); // vertical slider adds to the right column @@ -93,8 +100,8 @@ public class RangedGroup extends Widget { this.clippedContent = new Group( new GridLayout(1, 0f, 0f, Alignment.None)); this.clippedContent.setFixedSize(contentSize); this.clippedContent.addShape(content); - this.clippedContent.setClipOnBox(true); addShape(clippedContent); + clipCullingScale = cullingScale; if( null != horizSliderParam ) { horizSlider = new RangeSlider(renderModes, horizSliderParam.size, @@ -134,6 +141,7 @@ public class RangedGroup extends Widget { public Group getContent() { return content; } public Vec2f getContentSize() { return clippedContent.getFixedSize(); } + public Vec3f getClipCullingScale() { return clipCullingScale; } public Group getClippedContent() { return clippedContent; } public RangeSlider getHorizSlider() { return horizSlider; } public RangeSlider getVertSlider() { return vertSlider; } @@ -156,5 +164,15 @@ public class RangedGroup extends Widget { contentPosZero.setY( null != vertSlider && vertSlider.isInverted() ? contentSize.y() - b.getHeight() : 0 ); } } - + @Override + protected void drawImpl0(final GL2ES2 gl, final RegionRenderer renderer, final int[] sampleCount, final Vec4f rgba) { + if( content.isVisible() ) { + // Mv pre-multiplied AABBox, clippedContent is on same PMV + final AABBox clipBBox = clippedContent.getBounds().transform(renderer.getMatrix().getMv(), tempBB); + content.setClipBBox(clipBBox, clipCullingScale); + super.drawImpl0(gl, renderer, sampleCount, rgba); + content.setClipBBox(null, clipCullingScale); + } + } + private final AABBox tempBB = new AABBox(); // OK, synchronized } |