28package com.jogamp.graph.curve;
30import java.io.PrintStream;
31import java.nio.FloatBuffer;
32import java.nio.IntBuffer;
33import java.nio.ShortBuffer;
34import java.util.ArrayList;
36import java.util.Locale;
37import java.util.concurrent.TimeUnit;
39import jogamp.opengl.Debug;
41import com.jogamp.graph.geom.Triangle;
42import com.jogamp.graph.geom.Vertex;
43import com.jogamp.math.Vec3f;
44import com.jogamp.math.Vec4f;
45import com.jogamp.math.geom.AABBox;
46import com.jogamp.math.geom.Frustum;
47import com.jogamp.math.geom.plane.AffineTransform;
48import com.jogamp.common.nio.Buffers;
49import com.jogamp.common.os.Clock;
50import com.jogamp.common.util.PerfCounterCtrl;
51import com.jogamp.graph.curve.opengl.GLRegion;
52import com.jogamp.opengl.GLCapabilitiesImmutable;
53import com.jogamp.opengl.GLProfile;
54import com.jogamp.opengl.util.texture.TextureSequence;
64 public static final boolean DEBUG_ALL_EVENT = Debug.debugExplicit(
"graph.curve.AllEvent");
65 public static final boolean DEBUG_INSTANCE = Debug.debugExplicit(
"graph.curve.Instance");
186 private final int renderModes;
187 private final boolean use_int32_idx;
188 private final int max_indices;
190 private int numVertices = 0;
194 public static final boolean isRenderModeSet(
final int renderModes,
final int mask) {
return mask == ( renderModes & mask ); }
195 public static final int setRenderMode(
int renderModes,
final int mask,
final boolean v) {
if( v ) { renderModes |= mask; }
else { renderModes &= ~mask; };
return renderModes; }
198 public static boolean isVBAA(
final int renderModes) {
203 public static boolean isMSAA(
final int renderModes) {
208 public static boolean isGraphAA(
final int renderModes) {
209 return 0 != ( renderModes & Region.AA_RENDERING_MASK );
213 public static boolean isTwoPass(
final int renderModes) {
214 return 0 != ( renderModes & Region.AA_RENDERING_MASK );
261 return "vbaa"+curveS+cChanS+cTexS;
263 return "msaa"+curveS+cChanS+cTexS;
265 return "norm"+curveS+cChanS+cTexS;
280 public static String
getRenderModeString(
final int renderModes,
final int graphAAQuality,
final int graphSampleCount,
final int fsaaSampleCount) {
282 return String.format((Locale)
null,
"%s-qu-s%02d-fsaa%d",
Region.
getRenderModeString(renderModes), graphSampleCount, fsaaSampleCount);
284 return String.format((Locale)
null,
"%s-q%01d-s%02d-fsaa%d",
Region.
getRenderModeString(renderModes), graphAAQuality, graphSampleCount, fsaaSampleCount);
288 protected Region(
final int regionRenderModes,
final boolean use_int32_idx) {
289 this.renderModes = regionRenderModes;
290 this.use_int32_idx = use_int32_idx;
291 if( use_int32_idx ) {
305 public final boolean usesI32Idx() {
return this.use_int32_idx; }
319 public abstract boolean growBuffer(
int verticesCount,
int indicesCount);
339 protected abstract void pushIndices(
int idx1,
int idx2,
int idx3);
352 public final boolean isRenderModeSet(
final int mask) {
return mask == ( renderModes & mask ); }
413 if(
null != transform ) {
424 private void pushNewVerticesImpl(
final Vertex vertIn1,
final Vertex vertIn2,
final Vertex vertIn3,
final AffineTransform transform,
final Vec4f rgba) {
426 if(
null != transform ) {
427 final Vec3f coordsEx1 = transform.transform(vertIn1.getCoord(),
new Vec3f());
428 final Vec3f coordsEx2 = transform.transform(vertIn2.getCoord(),
new Vec3f());
429 final Vec3f coordsEx3 = transform.transform(vertIn3.getCoord(),
new Vec3f());
434 vertIn1.getTexCoord(), vertIn2.getTexCoord(), vertIn3.getTexCoord(), rgba);
439 pushVertices(vertIn1.getCoord(), vertIn2.getCoord(), vertIn3.getCoord(),
440 vertIn1.getTexCoord(), vertIn2.getTexCoord(), vertIn3.getTexCoord(), rgba);
445 @SuppressWarnings(
"unused")
446 private
void pushNewVertexIdxImpl(final Vertex vertIn, final AffineTransform transform, final Vec4f rgba) {
449 pushNewVertexImpl(vertIn, transform, rgba);
454 private void pushNewVerticesIdxImpl(
final Vertex vertIn1,
final Vertex vertIn2,
final Vertex vertIn3,
final AffineTransform transform,
final Vec4f rgba) {
456 pushIndices(numVertices, numVertices+1, numVertices+2);
457 pushNewVerticesImpl(vertIn1, vertIn2, vertIn3, transform, rgba);
461 protected static void put3i(
final IntBuffer b,
final int v1,
final int v2,
final int v3) {
462 b.put(v1); b.put(v2); b.put(v3);
464 protected static void put3s(
final ShortBuffer b,
final short v1,
final short v2,
final short v3) {
465 b.put(v1); b.put(v2); b.put(v3);
467 protected static void put3f(
final FloatBuffer b,
final Vec3f v) {
468 b.put(v.x()); b.put(v.y()); b.put(v.z());
470 protected static void put4f(
final FloatBuffer b,
final float v1,
final float v2,
final float v3,
final float v4) {
471 b.put(v1); b.put(v2); b.put(v3); b.put(v4);
473 protected static void put4f(
final FloatBuffer b,
final Vec4f v) {
474 b.put(v.x()); b.put(v.y()); b.put(v.z()); b.put(v.w());
484 long td_vertices = 0;
485 long td_tri_push_idx = 0;
486 long td_tri_push_vertidx = 0;
487 long td_tri_misc = 0;
488 long td_tri_total = 0;
492 public void print(
final PrintStream out) {
493 final long tac_ns_triangles_self = td_tri_total - td_tri_push_vertidx - td_tri_push_idx - td_tri_misc;
494 final long tac_ns_total_self = td_total - td_tri_total - td_vertices;
495 out.printf(
"Region.add(): count %,3d, total %,5d [ms], per-add %,4.2f [ns]%n", count, TimeUnit.NANOSECONDS.toMillis(td_total), ((
double)td_total/count));
496 out.printf(
" total self %,5d [ms], per-add %,4.2f [ns]%n", TimeUnit.NANOSECONDS.toMillis(tac_ns_total_self), ((
double)tac_ns_total_self/count));
497 out.printf(
" vertices %,5d [ms], per-add %,4.2f [ns]%n", TimeUnit.NANOSECONDS.toMillis(td_vertices), ((
double)td_vertices/count));
498 out.printf(
" triangles total %,5d [ms], per-add %,4.2f [ns]%n", TimeUnit.NANOSECONDS.toMillis(td_tri_total), ((
double)td_tri_total/count));
499 out.printf(
" triangles self %,5d [ms], per-add %,4.2f [ns]%n", TimeUnit.NANOSECONDS.toMillis(tac_ns_triangles_self), ((
double)tac_ns_triangles_self/count));
500 out.printf(
" tri misc %,5d [ms], per-add %,4.2f [ns]%n", TimeUnit.NANOSECONDS.toMillis(td_tri_misc), ((
double)td_tri_misc/count));
501 out.printf(
" tri p-idx %,5d [ms], per-add %,4.2f [ns]%n", TimeUnit.NANOSECONDS.toMillis(td_tri_push_idx), ((
double)td_tri_push_idx/count));
502 out.printf(
" tri p-vertidx %,5d [ms], per-add %,4.2f [ns]%n", TimeUnit.NANOSECONDS.toMillis(td_tri_push_vertidx), ((
double)td_tri_push_vertidx/count));
505 public void clear() {
508 td_tri_push_vertidx = 0;
515 private Perf perf =
null;
517 private final PerfCounterCtrl perfCounterCtrl =
new PerfCounterCtrl() {
519 public void enable(
final boolean enable) {
532 public void clear() {
539 public long getTotalDuration() {
541 return perf.td_total;
548 public void print(
final PrintStream out) {
573 if(
null == shape ) {
574 return vertIndexCount;
577 final ArrayList<Vertex> vertsIn = shape.
getVertices();
580 vertIndexCount[1] += trisIn.size() * 3;
582 return vertIndexCount;
598 public static final int[]
countOutlineShapes(
final List<OutlineShape> shapes,
final int[] vertIndexCount) {
599 for (
int i = 0; i < shapes.size(); i++) {
602 return vertIndexCount;
624 shapeBoxT = shapeBox;
631 addOutlineShape0(shape, t, rgbaColor);
636 addOutlineShape1(shape, t, rgbaColor);
642 final ArrayList<Vertex> vertsIn = shape.
getVertices();
645 final int indexCount = trisIn.size() * 3;
650 final int idxOffset = numVertices;
651 if( vertsIn.size() >= 3 ) {
655 for(
int i=0; i<vertsIn.size(); i++) {
656 pushNewVertexImpl(vertsIn.get(i), t, rgbaColor);
658 final int trisIn_sz = trisIn.size();
659 for(
int i=0; i < trisIn_sz; ++i) {
660 final Triangle triIn = trisIn.get(i);
663 final Vertex[] triInVertices = triIn.getVertices();
664 final int tv0Idx = triInVertices[0].getId();
666 if ( max_indices - idxOffset > tv0Idx ) {
670 triInVertices[1].getId()+idxOffset,
671 triInVertices[2].getId()+idxOffset);
675 pushNewVerticesIdxImpl(triInVertices[0], triInVertices[1], triInVertices[2], t, rgbaColor);
681 private final void addOutlineShape1(
final OutlineShape shape,
final AffineTransform t,
final Vec4f rgbaColor) {
683 final long t0 = Clock.currentNanos();
684 final List<Triangle> trisIn = shape.getTriangles(OutlineShape.VerticesState.QUADRATIC_NURBS);
685 final ArrayList<Vertex> vertsIn = shape.getVertices();
687 final int addedVerticeCount = shape.getAddedVerticeCount();
688 final int verticeCount = vertsIn.size() + addedVerticeCount;
689 final int indexCount = trisIn.size() * 3;
691 System.err.println(
"Region.addOutlineShape().0: tris: "+trisIn.size()+
", verts "+vertsIn.size()+
", transform "+t);
692 System.err.println(
"Region.addOutlineShape().0: VerticeCount "+vertsIn.size()+
" + "+addedVerticeCount+
" = "+verticeCount);
693 System.err.println(
"Region.addOutlineShape().0: IndexCount "+indexCount);
698 final int idxOffset = numVertices;
699 int vertsVNewIdxCount = 0, vertsTMovIdxCount = 0, vertsTNewIdxCount = 0, tris = 0;
700 final int vertsDupCountV = 0, vertsDupCountT = 0, vertsKnownMovedT = 0;
701 if( vertsIn.size() >= 3 ) {
705 for(
int i=0; i<vertsIn.size(); i++) {
706 pushNewVertexImpl(vertsIn.get(i), t, rgbaColor);
709 final long t1 = Clock.currentNanos();
710 perf.td_vertices += t1 - t0;
714 final int trisIn_sz = trisIn.size();
715 for(
int i=0; i < trisIn_sz; ++i) {
716 final Triangle triIn = trisIn.get(i);
717 final long t2 = Clock.currentNanos();
723 final Vertex[] triInVertices = triIn.getVertices();
724 final int tv0Idx = triInVertices[0].getId();
726 perf.td_tri_misc += Clock.currentNanos() - t2;
727 if ( max_indices - idxOffset > tv0Idx ) {
732 final long tpi = Clock.currentNanos();
734 triInVertices[1].getId()+idxOffset,
735 triInVertices[2].getId()+idxOffset);
736 perf.td_tri_push_idx += Clock.currentNanos() - tpi;
737 vertsTMovIdxCount+=3;
743 final long tpvi = Clock.currentNanos();
744 pushNewVerticesIdxImpl(triInVertices[0], triInVertices[1], triInVertices[2], t, rgbaColor);
745 perf.td_tri_push_vertidx += Clock.currentNanos() - tpvi;
746 vertsTNewIdxCount+=3;
750 final long ttriX = Clock.currentNanos();
751 perf.td_tri_total += ttriX - t1;
752 perf.td_total += ttriX - t0;
755 System.err.println(
"Region.addOutlineShape().X: idx[ui32 "+
usesI32Idx()+
", offset "+idxOffset+
"], tris: "+tris+
", verts [idx "+vertsTNewIdxCount+
", add "+vertsTNewIdxCount+
" = "+(vertsVNewIdxCount+vertsTNewIdxCount)+
"]");
756 System.err.println(
"Region.addOutlineShape().X: verts: idx[v-new "+vertsVNewIdxCount+
", t-new "+vertsTNewIdxCount+
" = "+(vertsVNewIdxCount+vertsTNewIdxCount)+
"]");
757 System.err.println(
"Region.addOutlineShape().X: verts: idx t-moved "+vertsTMovIdxCount+
", numVertices "+numVertices);
758 System.err.println(
"Region.addOutlineShape().X: verts: v-dups "+vertsDupCountV+
", t-dups "+vertsDupCountT+
", t-known "+vertsKnownMovedT);
760 System.err.println(
"Region.addOutlineShape().X: box "+
box);
777 for (
int i = 0; i < shapes.size(); i++) {
829 return "Region[0x"+Integer.toHexString(hashCode())+
", "+
getRenderModeString(this.renderModes)+
", dirty "+dirty+
", vertices "+numVertices+
", box "+
box+
"]";
A Generic shape objects which is defined by a list of Outlines.
final int getAddedVerticeCount()
Return the number of newly added vertices during getTriangles(VerticesState) while transforming the o...
final ArrayList< Vertex > getVertices()
Return list of concatenated vertices associated with all Outlines of this object.
final ArrayList< Triangle > getTriangles(final VerticesState destinationType)
Triangulate the OutlineShape generating a list of triangles, while transformOutlines(VerticesState) b...
Abstract Outline shape representation define the method an OutlineShape(s) is bound and rendered.
static final int MIN_AA_QUALITY
Minimum pass2 AA-quality rendering {@value} for Graph Region AA render-modes: VBAA_RENDERING_BIT.
static boolean isTwoPass(final int renderModes)
Returns true if given renderModes has any of Region#AA_RENDERING_MASK set.
static final int setRenderMode(int renderModes, final int mask, final boolean v)
final boolean isStateDirty()
Returns true if this region's state is dirty, see markStateDirty().
static final int MSAA_RENDERING_BIT
Rendering-Mode bit for Region.
final boolean isVBAA()
Returns true if capable of two pass rendering - VBAA, otherwise false.
final boolean hasColorChannel()
Returns true if getRenderModes() has a color channel, i.e.
static final int clipAAQuality(final int v)
Returns clipped AA quality value to [Region#MIN_AA_QUALITY..Region#MAX_AA_QUALITY].
static final int VARWEIGHT_RENDERING_BIT
Rendering-Mode bit for Region.
static final boolean isRenderModeSet(final int renderModes, final int mask)
static String getRenderModeString(final int renderModes, final int graphAAQuality, final int graphSampleCount, final int fsaaSampleCount)
Return a unique technical description string for renderModes and sample counts as follows:
final void addOutlineShape(final OutlineShape shape, final AffineTransform t, final Vec4f rgbaColor)
Add the given OutlineShape to this region with the given optional AffineTransform.
static final int DEFAULT_AA_QUALITY
Default pass2 AA-quality rendering {@value} for Graph Region AA render-modes: VBAA_RENDERING_BIT.
static final int GL_UINT16_MAX
static void put3f(final FloatBuffer b, final Vec3f v)
static boolean isVBAA(final int renderModes)
Returns true if given renderModes has Region#VBAA_RENDERING_BIT set.
static final int MIN_AA_SAMPLE_COUNT
Minimum pass2 AA sample count {@value} for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT or...
static boolean hasVariableWeight(final int renderModes)
Returns true if render mode capable of variable weights, i.e.
static final int COLORCHANNEL_RENDERING_BIT
Rendering-Mode bit for Region to optionally enable a color-channel per vertex.
final Frustum getFrustum()
See setFrustum(Frustum).
final void addOutlineShapes(final List< OutlineShape > shapes, final AffineTransform transform, final Vec4f rgbaColor)
Add the given list of OutlineShapes to this region with the given optional AffineTransform.
static final boolean DEBUG_ALL_EVENT
static final int COLORTEXTURE_RENDERING_BIT
Rendering-Mode bit for Region.
abstract void pushIndex(int idx)
static final int clipAASampleCount(final int v)
Returns clipped AA sample-count to [Region#MIN_AA_SAMPLE_COUNT..Region#MAX_AA_SAMPLE_COUNT].
static String getRenderModeString(final int renderModes)
Returns a unique technical description string for renderModes as follows:
static final int DEFAULT_TWO_PASS_TEXTURE_UNIT
final boolean hasColorTexture()
Returns true if render mode has a color texture, i.e.
abstract void pushVertex(final Vec3f coords, final Vec3f texParams, Vec4f rgba)
static boolean isMSAA(final int renderModes)
Returns true if given renderModes has Region#MSAA_RENDERING_BIT set.
final boolean hasVariableWeight()
Returns true if capable of variable weights, otherwise false.
static final int DEFAULT_AA_SAMPLE_COUNT
Default pass2 AA sample count {@value} for Graph Region AA render-modes: VBAA_RENDERING_BIT or Region...
final void markStateDirty()
Mark this region's render-state dirty, i.e.
final void clearDirtyBits(final int v)
See markShapeDirty() and markStateDirty().
abstract void pushVertices(final Vec3f coords1, final Vec3f coords2, final Vec3f coords3, final Vec3f texParams1, final Vec3f texParams2, final Vec3f texParams3, Vec4f rgba)
PerfCounterCtrl perfCounter()
static final int[] countOutlineShape(final OutlineShape shape, final int[] vertIndexCount)
Count required number of vertices and indices adding to given int[2] vertIndexCount array.
static final int[] countOutlineShapes(final List< OutlineShape > shapes, final int[] vertIndexCount)
Count required number of vertices and indices adding to given int[2] vertIndexCount array.
final boolean isShapeDirty()
Returns true if this region's shape are dirty, see markShapeDirty().
static final int MAX_AA_QUALITY
Maximum pass2 AA-quality rendering {@value} for Graph Region AA render-modes: VBAA_RENDERING_BIT.
final boolean isMSAA()
Returns true if capable of two pass rendering - MSAA, otherwise false.
static final int AA_RENDERING_MASK
2-pass rendering bit-mask including MSAA_RENDERING_BIT and VBAA_RENDERING_BIT.
final void setFrustum(final Frustum frustum)
Set Frustum culling for addOutlineShape(OutlineShape, AffineTransform, float[]).
static boolean isGraphAA(final int renderModes)
Returns true if given renderModes has any of Region#AA_RENDERING_MASK set.
static final int DIRTY_STATE
static final int DIRTY_SHAPE
static final int NORM_RENDERING_BIT
Rendering-Mode bit for Region.
static final boolean DEBUG_INSTANCE
static void put4f(final FloatBuffer b, final float v1, final float v2, final float v3, final float v4)
Region(final int regionRenderModes, final boolean use_int32_idx)
final int getRenderModes()
Returns bit-field of render modes, see create(..).
final boolean isRenderModeSet(final int mask)
static boolean hasColorChannel(final int renderModes)
Returns true if render mode has a color channel, i.e.
static final int VBAA_RENDERING_BIT
Rendering-Mode bit for Region.
static final int MAX_AA_SAMPLE_COUNT
Maximum pass2 AA sample count {@value} for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT or...
static final boolean DEBUG
Debug flag for [com.
static void put3i(final IntBuffer b, final int v1, final int v2, final int v3)
abstract void printBufferStats(PrintStream out)
Print implementation buffer stats like detailed and total size and capacity in bytes etc.
abstract boolean growBuffer(int verticesCount, int indicesCount)
Increase the renderer buffers if necessary to add given counts of vertices- and index elements.
abstract void pushIndices(int idx1, int idx2, int idx3)
final boolean usesI32Idx()
Returns true if implementation uses int32_t sized indices implying at least a GLProfile#isGL2ES3() al...
static void put3s(final ShortBuffer b, final short v1, final short v2, final short v3)
final void markShapeDirty()
Mark this region's shape dirty, i.e.
static final int GL_INT32_MAX
static boolean hasColorTexture(final int renderModes)
Returns true if render mode has a color texture, i.e.
abstract boolean setBufferCapacity(int verticesCount, int indicesCount)
Set the renderer buffers pre-emptively for given vertices- and index counts.
static void put4f(final FloatBuffer b, final Vec4f v)
A Vertex exposing Vec3f vertex- and texture-coordinates.
final Vec3f getTexCoord()
3D Vector based upon three float components.
4D Vector based upon four float components.
Axis Aligned Bounding Box.
final AABBox reset()
Resets this box to the inverse low/high, allowing the next resize(float, float, float) command to hit...
final AABBox resize(final AABBox newBox)
Resize the AABBox to encapsulate another AABox.
Providing frustum planes derived by different inputs (P*MV, ..) used to classify objects.
final boolean isOutside(final AABBox box)
Returns whether the given AABBox is completely outside of this frustum.
Outline's vertices have undefined state until transformed.