@@ -97,6 +97,7 @@ public class PShapeOpenGL extends PShape {
97
97
98
98
protected HashSet <PImage > textures ;
99
99
protected boolean strokedTexture ;
100
+ protected boolean untexChild ;
100
101
101
102
// ........................................................
102
103
@@ -425,6 +426,8 @@ public void addChild(PShape who) {
425
426
for (PImage tex : c3d .textures ) {
426
427
addTexture (tex );
427
428
}
429
+ } else {
430
+ untexChild (true );
428
431
}
429
432
if (c3d .strokedTexture ) {
430
433
strokedTexture (true );
@@ -435,6 +438,8 @@ public void addChild(PShape who) {
435
438
if (c3d .stroke ) {
436
439
strokedTexture (true );
437
440
}
441
+ } else {
442
+ untexChild (true );
438
443
}
439
444
}
440
445
@@ -462,6 +467,8 @@ public void addChild(PShape who, int idx) {
462
467
for (PImage tex : c3d .textures ) {
463
468
addTexture (tex );
464
469
}
470
+ } else {
471
+ untexChild (true );
465
472
}
466
473
if (c3d .strokedTexture ) {
467
474
strokedTexture (true );
@@ -472,6 +479,8 @@ public void addChild(PShape who, int idx) {
472
479
if (c3d .stroke ) {
473
480
strokedTexture (true );
474
481
}
482
+ } else {
483
+ untexChild (true );
475
484
}
476
485
}
477
486
@@ -487,6 +496,8 @@ public void addChild(PShape who, int idx) {
487
496
@ Override
488
497
public void removeChild (int idx ) {
489
498
super .removeChild (idx );
499
+ strokedTexture (false );
500
+ untexChild (false );
490
501
markForTessellation ();
491
502
}
492
503
@@ -792,7 +803,7 @@ protected void setTextureImpl(PImage tex) {
792
803
}
793
804
794
805
if (image0 != tex && parent != null ) {
795
- ((PShapeOpenGL )parent ).removeTexture (tex );
806
+ ((PShapeOpenGL )parent ).removeTexture (image0 , this );
796
807
}
797
808
if (parent != null ) {
798
809
((PShapeOpenGL )parent ).addTexture (image );
@@ -845,14 +856,14 @@ protected void addTexture(PImage tex) {
845
856
}
846
857
847
858
848
- protected void removeTexture (PImage tex ) {
859
+ protected void removeTexture (PImage tex , PShapeOpenGL caller ) {
849
860
if (textures == null || !textures .contains (tex )) return ; // Nothing to remove.
850
861
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...
853
863
boolean childHasTex = false ;
854
864
for (int i = 0 ; i < childCount ; i ++) {
855
865
PShapeOpenGL child = (PShapeOpenGL ) children [i ];
866
+ if (child == caller ) continue ;
856
867
if (child .hasTexture (tex )) {
857
868
childHasTex = true ;
858
869
break ;
@@ -870,38 +881,76 @@ protected void removeTexture(PImage tex) {
870
881
// Since this shape and all its child shapes don't contain
871
882
// tex anymore, we now can remove it from the parent.
872
883
if (parent != null ) {
873
- ((PShapeOpenGL )parent ).removeTexture (tex );
884
+ ((PShapeOpenGL )parent ).removeTexture (tex , this );
874
885
}
875
886
}
876
887
877
888
878
889
protected void strokedTexture (boolean newValue ) {
890
+ strokedTexture (newValue , null );
891
+ }
892
+
893
+
894
+ protected void strokedTexture (boolean newValue , PShapeOpenGL caller ) {
879
895
if (strokedTexture == newValue ) return ; // Nothing to change.
880
896
881
897
if (newValue ) {
882
898
strokedTexture = true ;
883
899
} 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 ;
887
902
for (int i = 0 ; i < childCount ; i ++) {
888
903
PShapeOpenGL child = (PShapeOpenGL ) children [i ];
904
+ if (child == caller ) continue ;
889
905
if (child .hasStrokedTexture ()) {
890
- childHasStrokedTex = true ;
906
+ strokedTexture = true ;
891
907
break ;
892
908
}
893
909
}
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.
894
926
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
+ }
899
939
}
900
940
}
901
941
902
942
// Now we can update the parent shape.
903
943
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 ;
905
954
}
906
955
}
907
956
@@ -2797,6 +2846,11 @@ protected void tessellateImpl() {
2797
2846
lastPointIndexCache = -1 ;
2798
2847
2799
2848
if (family == GROUP ) {
2849
+ if (polyAttribs == null ) {
2850
+ polyAttribs = PGraphicsOpenGL .newAttributeMap ();
2851
+ collectPolyAttribs ();
2852
+ }
2853
+
2800
2854
for (int i = 0 ; i < childCount ; i ++) {
2801
2855
PShapeOpenGL child = (PShapeOpenGL ) children [i ];
2802
2856
child .tessellateImpl ();
@@ -3255,7 +3309,8 @@ protected void tessellateSphere() {
3255
3309
int [] indices = inGeo .addSphere (r , nu , nv , fill , stroke );
3256
3310
tessellator .tessellateTriangles (indices );
3257
3311
3258
- if (savedDetailU != nu || savedDetailV != nv ) {
3312
+ if ((0 < savedDetailU && savedDetailU != nu ) ||
3313
+ (0 < savedDetailV && savedDetailV != nv )) {
3259
3314
pg .sphereDetail (savedDetailU , savedDetailV );
3260
3315
}
3261
3316
}
@@ -4599,13 +4654,14 @@ public void draw(PGraphics g) {
4599
4654
4600
4655
4601
4656
// 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,
4603
4659
// so they cannot rendered in a single call.
4604
4660
// Or accurate 2D mode is enabled, which forces each
4605
4661
// shape to be rendered separately.
4606
4662
protected boolean fragmentedGroup (PGraphicsOpenGL g ) {
4607
4663
return g .getHint (DISABLE_OPTIMIZED_STROKE ) ||
4608
- (textures != null && 1 < textures .size ()) ||
4664
+ (textures != null && ( 1 < textures .size () || untexChild )) ||
4609
4665
strokedTexture ;
4610
4666
}
4611
4667
0 commit comments