@@ -97,6 +97,7 @@ public class PShapeOpenGL extends PShape {
9797
9898 protected HashSet <PImage > textures ;
9999 protected boolean strokedTexture ;
100+ protected boolean untexChild ;
100101
101102 // ........................................................
102103
@@ -425,6 +426,8 @@ public void addChild(PShape who) {
425426 for (PImage tex : c3d .textures ) {
426427 addTexture (tex );
427428 }
429+ } else {
430+ untexChild (true );
428431 }
429432 if (c3d .strokedTexture ) {
430433 strokedTexture (true );
@@ -435,6 +438,8 @@ public void addChild(PShape who) {
435438 if (c3d .stroke ) {
436439 strokedTexture (true );
437440 }
441+ } else {
442+ untexChild (true );
438443 }
439444 }
440445
@@ -462,6 +467,8 @@ public void addChild(PShape who, int idx) {
462467 for (PImage tex : c3d .textures ) {
463468 addTexture (tex );
464469 }
470+ } else {
471+ untexChild (true );
465472 }
466473 if (c3d .strokedTexture ) {
467474 strokedTexture (true );
@@ -472,6 +479,8 @@ public void addChild(PShape who, int idx) {
472479 if (c3d .stroke ) {
473480 strokedTexture (true );
474481 }
482+ } else {
483+ untexChild (true );
475484 }
476485 }
477486
@@ -487,6 +496,8 @@ public void addChild(PShape who, int idx) {
487496 @ Override
488497 public void removeChild (int idx ) {
489498 super .removeChild (idx );
499+ strokedTexture (false );
500+ untexChild (false );
490501 markForTessellation ();
491502 }
492503
@@ -792,7 +803,7 @@ protected void setTextureImpl(PImage tex) {
792803 }
793804
794805 if (image0 != tex && parent != null ) {
795- ((PShapeOpenGL )parent ).removeTexture (tex );
806+ ((PShapeOpenGL )parent ).removeTexture (image0 , this );
796807 }
797808 if (parent != null ) {
798809 ((PShapeOpenGL )parent ).addTexture (image );
@@ -845,14 +856,14 @@ protected void addTexture(PImage tex) {
845856 }
846857
847858
848- protected void removeTexture (PImage tex ) {
859+ protected void removeTexture (PImage tex , PShapeOpenGL caller ) {
849860 if (textures == null || !textures .contains (tex )) return ; // Nothing to remove.
850861
851- // First check that none of the child shapes
852- // have texture tex...
862+ // First check that none of the child shapes have texture tex...
853863 boolean childHasTex = false ;
854864 for (int i = 0 ; i < childCount ; i ++) {
855865 PShapeOpenGL child = (PShapeOpenGL ) children [i ];
866+ if (child == caller ) continue ;
856867 if (child .hasTexture (tex )) {
857868 childHasTex = true ;
858869 break ;
@@ -870,38 +881,76 @@ protected void removeTexture(PImage tex) {
870881 // Since this shape and all its child shapes don't contain
871882 // tex anymore, we now can remove it from the parent.
872883 if (parent != null ) {
873- ((PShapeOpenGL )parent ).removeTexture (tex );
884+ ((PShapeOpenGL )parent ).removeTexture (tex , this );
874885 }
875886 }
876887
877888
878889 protected void strokedTexture (boolean newValue ) {
890+ strokedTexture (newValue , null );
891+ }
892+
893+
894+ protected void strokedTexture (boolean newValue , PShapeOpenGL caller ) {
879895 if (strokedTexture == newValue ) return ; // Nothing to change.
880896
881897 if (newValue ) {
882898 strokedTexture = true ;
883899 } else {
884- // First check that none of the child shapes
885- // have have a stroked texture...
886- boolean childHasStrokedTex = false ;
900+ // Check that none of the child shapes have a stroked texture...
901+ strokedTexture = false ;
887902 for (int i = 0 ; i < childCount ; i ++) {
888903 PShapeOpenGL child = (PShapeOpenGL ) children [i ];
904+ if (child == caller ) continue ;
889905 if (child .hasStrokedTexture ()) {
890- childHasStrokedTex = true ;
906+ strokedTexture = true ;
891907 break ;
892908 }
893909 }
910+ }
911+
912+ // Now we can update the parent shape.
913+ if (parent != null ) {
914+ ((PShapeOpenGL )parent ).strokedTexture (newValue , this );
915+ }
916+ }
917+
918+
919+ protected void untexChild (boolean newValue ) {
920+ untexChild (newValue , null );
921+ }
922+
923+
924+ protected void untexChild (boolean newValue , PShapeOpenGL caller ) {
925+ if (untexChild == newValue ) return ; // Nothing to change.
894926
895- if (!childHasStrokedTex ) {
896- // ...if not, it is safe to mark this shape as without
897- // stroked texture.
898- strokedTexture = false ;
927+ if (newValue ) {
928+ untexChild = true ;
929+ } else {
930+ // Check if any of the child shapes is not textured...
931+ untexChild = false ;
932+ for (int i = 0 ; i < childCount ; i ++) {
933+ PShapeOpenGL child = (PShapeOpenGL ) children [i ];
934+ if (child == caller ) continue ;
935+ if (!child .hasTexture ()) {
936+ untexChild = true ;
937+ break ;
938+ }
899939 }
900940 }
901941
902942 // Now we can update the parent shape.
903943 if (parent != null ) {
904- ((PShapeOpenGL )parent ).strokedTexture (newValue );
944+ ((PShapeOpenGL )parent ).untexChild (newValue , this );
945+ }
946+ }
947+
948+
949+ protected boolean hasTexture () {
950+ if (family == GROUP ) {
951+ return textures != null && 0 < textures .size ();
952+ } else {
953+ return image != null ;
905954 }
906955 }
907956
@@ -2797,6 +2846,11 @@ protected void tessellateImpl() {
27972846 lastPointIndexCache = -1 ;
27982847
27992848 if (family == GROUP ) {
2849+ if (polyAttribs == null ) {
2850+ polyAttribs = PGraphicsOpenGL .newAttributeMap ();
2851+ collectPolyAttribs ();
2852+ }
2853+
28002854 for (int i = 0 ; i < childCount ; i ++) {
28012855 PShapeOpenGL child = (PShapeOpenGL ) children [i ];
28022856 child .tessellateImpl ();
@@ -3255,7 +3309,8 @@ protected void tessellateSphere() {
32553309 int [] indices = inGeo .addSphere (r , nu , nv , fill , stroke );
32563310 tessellator .tessellateTriangles (indices );
32573311
3258- if (savedDetailU != nu || savedDetailV != nv ) {
3312+ if ((0 < savedDetailU && savedDetailU != nu ) ||
3313+ (0 < savedDetailV && savedDetailV != nv )) {
32593314 pg .sphereDetail (savedDetailU , savedDetailV );
32603315 }
32613316 }
@@ -4599,13 +4654,14 @@ public void draw(PGraphics g) {
45994654
46004655
46014656 // Returns true if some child shapes below this one either
4602- // use different texture maps or have stroked textures,
4657+ // use different texture maps (or only one texture is used by some while
4658+ // others are untextured), or have stroked textures,
46034659 // so they cannot rendered in a single call.
46044660 // Or accurate 2D mode is enabled, which forces each
46054661 // shape to be rendered separately.
46064662 protected boolean fragmentedGroup (PGraphicsOpenGL g ) {
46074663 return g .getHint (DISABLE_OPTIMIZED_STROKE ) ||
4608- (textures != null && 1 < textures .size ()) ||
4664+ (textures != null && ( 1 < textures .size () || untexChild )) ||
46094665 strokedTexture ;
46104666 }
46114667
0 commit comments