@@ -51,6 +51,7 @@ class SoVBO;
5151#include < Inventor/elements/SoVertexAttributeElement.h>
5252
5353#include " elements/SoLazyElementP.h"
54+ #include " shapenodes/SoShapeGLRenderP.h"
5455
5556#include < cstring>
5657#include < cstdlib>
@@ -883,76 +884,112 @@ SoShape::getComplexityValue(SoAction * action)
883884*/
884885SbBool
885886SoShape::shouldGLRender (SoGLRenderAction * action)
887+ {
888+ SoShapeGLRenderContext context;
889+ const SoShapeGLRenderDecision decision =
890+ SoShapeGLRender::begin (this , action, context);
891+ if (decision == SoShapeGLRenderDecision::RenderShape) return TRUE ;
892+ if (decision == SoShapeGLRenderDecision::Stop) return FALSE ;
893+ if (!SoShapeGLRender::sortTriangles (this , action, context)) return FALSE ;
894+ return SoShapeGLRender::finish (this , action, context);
895+ }
896+
897+ SoShapeGLRenderDecision
898+ SoShapeGLRender::begin (SoShape * shape, SoGLRenderAction * action,
899+ SoShapeGLRenderContext & context)
886900{
887901 SoState * state = action->getState ();
888902
889903 const SoShapeStyleElement * shapestyle = SoShapeStyleElement::get (state);
890- unsigned int shapestyleflags = shapestyle->getFlags ();
904+ const unsigned int shapestyleflags = shapestyle->getFlags ();
905+ context.shapeStyleFlags = shapestyleflags;
906+ context.transparent = (shapestyleflags &
907+ (SoShapeStyleElement::TRANSP_TEXTURE |
908+ SoShapeStyleElement::TRANSP_MATERIAL )) != 0 ;
891909
892910 if (shapestyleflags & SoShapeStyleElement::INVISIBLE )
893- return FALSE ;
894-
895- if (PRIVATE (this )->bboxcache && !state->isCacheOpen () && !SoCullElement::completelyInside (state)) {
896- if (PRIVATE (this )->bboxcache ->isValid (state)) {
897- if (SoCullElement::cullTest (state, PRIVATE (this )->bboxcache ->getProjectedBox ())) {
898- return FALSE ;
911+ return SoShapeGLRenderDecision::Stop;
912+
913+ if (PRIVATE (shape)->bboxcache && !state->isCacheOpen () &&
914+ !SoCullElement::completelyInside (state)) {
915+ if (PRIVATE (shape)->bboxcache ->isValid (state)) {
916+ if (SoCullElement::cullTest (state,
917+ PRIVATE (shape)->bboxcache ->getProjectedBox ())) {
918+ return SoShapeGLRenderDecision::Stop;
899919 }
900920 }
901921 }
902922
903- SbBool transparent = (shapestyleflags & (SoShapeStyleElement::TRANSP_TEXTURE |
904- SoShapeStyleElement::TRANSP_MATERIAL )) != 0 ;
905-
906923 if (shapestyleflags & SoShapeStyleElement::SHADOWMAP ) {
907- if (transparent) return FALSE ;
924+ if (context. transparent ) return SoShapeGLRenderDecision::Stop ;
908925 int style = SoShadowStyleElement::get (state);
909- if (style & SoShadowStyleElement::CASTS_SHADOW ) return TRUE ;
910- return FALSE ;
926+ if (style & SoShadowStyleElement::CASTS_SHADOW ) {
927+ return SoShapeGLRenderDecision::RenderShape;
928+ }
929+ return SoShapeGLRenderDecision::Stop;
911930 }
912931
913- if (action->handleTransparency (transparent))
914- return FALSE ;
932+ if (action->handleTransparency (context. transparent ))
933+ return SoShapeGLRenderDecision::Stop ;
915934
916935 if (shapestyleflags & SoShapeStyleElement::BBOXCMPLX ) {
917- this ->GLRenderBoundingBox (action);
918- return FALSE ;
936+ shape ->GLRenderBoundingBox (action);
937+ return SoShapeGLRenderDecision::Stop ;
919938 }
920939
921- // test if we should sort triangles before rendering
922- if (transparent && (shapestyleflags & SoShapeStyleElement::TRANSP_SORTED_TRIANGLES )) {
923- // lock since pvcache is shared among all threads
924- PRIVATE (this )->lock ();
925- this ->validatePVCache (action);
940+ return SoShapeGLRenderDecision::Continue;
941+ }
926942
927- int arrays = SoPrimitiveVertexCache::NORMAL |SoPrimitiveVertexCache::COLOR ;
928- SoGLMultiTextureImageElement::Model model;
929- SbColor blendcolor;
930- SoGLImage * glimage = SoGLMultiTextureImageElement::get (state, 0 , model, blendcolor);
931- if (glimage) arrays |= SoPrimitiveVertexCache::TEXCOORD ;
943+ SbBool
944+ SoShapeGLRender::sortTriangles (SoShape * shape, SoGLRenderAction * action,
945+ const SoShapeGLRenderContext & context)
946+ {
947+ if (!context.transparent ||
948+ !(context.shapeStyleFlags & SoShapeStyleElement::TRANSP_SORTED_TRIANGLES )) {
949+ return TRUE ;
950+ }
932951
933- SoMaterialBundle mb (action);
934- mb.sendFirst ();
935- PRIVATE (this )->setupShapeHints (this , state);
936- PRIVATE (this )->pvcache ->depthSortTriangles (state);
937- PRIVATE (this )->pvcache ->renderTriangles (state, arrays);
938- if (PRIVATE (this )->pvcache ->getNumLineIndices () ||
939- PRIVATE (this )->pvcache ->getNumPointIndices ()) {
940- const SoNormalElement * nelem = SoNormalElement::getInstance (state);
941- if (nelem->getNum () == 0 ) {
942- glPushAttrib (GL_LIGHTING_BIT );
943- glDisable (GL_LIGHTING );
944- arrays &= SoPrimitiveVertexCache::NORMAL ;
945- }
946- PRIVATE (this )->pvcache ->renderLines (state, arrays);
947- PRIVATE (this )->pvcache ->renderPoints (state, arrays);
952+ SoState * state = action->getState ();
953+ // lock since pvcache is shared among all threads
954+ PRIVATE (shape)->lock ();
955+ shape->validatePVCache (action);
948956
949- if (nelem->getNum () == 0 ) {
950- glPopAttrib ();
951- }
957+ int arrays = SoPrimitiveVertexCache::NORMAL |SoPrimitiveVertexCache::COLOR ;
958+ SoGLMultiTextureImageElement::Model model;
959+ SbColor blendcolor;
960+ SoGLImage * glimage = SoGLMultiTextureImageElement::get (state, 0 , model, blendcolor);
961+ if (glimage) arrays |= SoPrimitiveVertexCache::TEXCOORD ;
962+
963+ SoMaterialBundle mb (action);
964+ mb.sendFirst ();
965+ PRIVATE (shape)->setupShapeHints (shape, state);
966+ PRIVATE (shape)->pvcache ->depthSortTriangles (state);
967+ PRIVATE (shape)->pvcache ->renderTriangles (state, arrays);
968+ if (PRIVATE (shape)->pvcache ->getNumLineIndices () ||
969+ PRIVATE (shape)->pvcache ->getNumPointIndices ()) {
970+ const SoNormalElement * nelem = SoNormalElement::getInstance (state);
971+ if (nelem->getNum () == 0 ) {
972+ glPushAttrib (GL_LIGHTING_BIT );
973+ glDisable (GL_LIGHTING );
974+ arrays &= SoPrimitiveVertexCache::NORMAL ;
975+ }
976+ PRIVATE (shape)->pvcache ->renderLines (state, arrays);
977+ PRIVATE (shape)->pvcache ->renderPoints (state, arrays);
978+
979+ if (nelem->getNum () == 0 ) {
980+ glPopAttrib ();
952981 }
953- PRIVATE (this )->unlock ();
954- return FALSE ; // tell shape _not_ to render
955982 }
983+ PRIVATE (shape)->unlock ();
984+ return FALSE ;
985+ }
986+
987+ SbBool
988+ SoShapeGLRender::finish (SoShape * shape, SoGLRenderAction * action,
989+ const SoShapeGLRenderContext & context)
990+ {
991+ SoState * state = action->getState ();
992+ const unsigned int shapestyleflags = context.shapeStyleFlags ;
956993
957994 if (shapestyleflags & SoShapeStyleElement::BIGIMAGE ) {
958995 SoGLMultiTextureImageElement::Model model;
@@ -984,10 +1021,10 @@ SoShape::shouldGLRender(SoGLRenderAction * action)
9841021 soshape_bigtexture * bigtex = soshape_get_bigtexture (shapedata, action->getCacheContext ());
9851022 shapedata->currentbigtexture = bigtex;
9861023 bigtex->beginShape (big, SoTextureQualityElement::get (state));
987- this ->generatePrimitives (action);
1024+ shape ->generatePrimitives (action);
9881025 // endShape() returns whether more/less detailed textures need to be
9891026 // fetched. We force a redraw if this is needed.
990- if (bigtex->endShape (state, this , mb) == FALSE ) {
1027+ if (bigtex->endShape (state, shape , mb) == FALSE ) {
9911028 action->getCurPath ()->getHead ()->touch ();
9921029 }
9931030 shapedata->rendermode = NORMAL ;
@@ -1002,13 +1039,13 @@ SoShape::shouldGLRender(SoGLRenderAction * action)
10021039 const SoNodeList & lights = SoLightElement::getLights (state);
10031040 if (lights.getLength ()) {
10041041 // lock since bumprender and pvcache is shared among all threads
1005- PRIVATE (this )->lock ();
1006- if (PRIVATE (this )->bumprender == NULL ) {
1007- PRIVATE (this )->bumprender = new soshape_bumprender;
1042+ PRIVATE (shape )->lock ();
1043+ if (PRIVATE (shape )->bumprender == NULL ) {
1044+ PRIVATE (shape )->bumprender = new soshape_bumprender;
10081045 }
1009- this ->validatePVCache (action);
1010- if (PRIVATE (this )->pvcache ->getNumTriangleIndices () == 0 ) {
1011- PRIVATE (this )->unlock ();
1046+ shape ->validatePVCache (action);
1047+ if (PRIVATE (shape )->pvcache ->getNumTriangleIndices () == 0 ) {
1048+ PRIVATE (shape )->unlock ();
10121049 return TRUE ;
10131050 }
10141051 SoGLLazyElement::getInstance (state)->send (state, SoLazyElement::ALL_MASK );
@@ -1018,7 +1055,7 @@ SoShape::shouldGLRender(SoGLRenderAction * action)
10181055 glDisable (GL_LIGHTING );
10191056
10201057 glColor3f (1 .0f , 1 .0f , 1 .0f );
1021- PRIVATE (this )->setupShapeHints (this , state);
1058+ PRIVATE (shape )->setupShapeHints (shape , state);
10221059 const int numlights = lights.getLength ();
10231060 for (int i = 0 ; i < numlights; i++) {
10241061 // fetch matrix that convert the light from its object space
@@ -1038,7 +1075,7 @@ SoShape::shouldGLRender(SoGLRenderAction * action)
10381075 //
10391076 // FIXME: about the above comment; i don't see any locking...?
10401077 // -mortene.
1041- PRIVATE (this )->bumprender ->renderBump (state, PRIVATE (this )->pvcache ,
1078+ PRIVATE (shape )->bumprender ->renderBump (state, PRIVATE (shape )->pvcache ,
10421079 (SoLight*) lights[i], m);
10431080
10441081 if (i == 0 ) glEnable (GL_BLEND );
@@ -1055,8 +1092,8 @@ SoShape::shouldGLRender(SoGLRenderAction * action)
10551092 SoLazyElement::DIFFUSE_MASK );
10561093 SoMaterialBundle mb (action);
10571094 mb.sendFirst ();
1058- PRIVATE (this )->setupShapeHints (this , state);
1059- PRIVATE (this )->bumprender ->renderNormal (state, PRIVATE (this )->pvcache );
1095+ PRIVATE (shape )->setupShapeHints (shape , state);
1096+ PRIVATE (shape )->bumprender ->renderNormal (state, PRIVATE (shape )->pvcache );
10601097
10611098 const SbColor spec = SoLazyElement::getSpecular (state);
10621099 if (spec[0 ] != 0 || spec[1 ] != 0 || spec[2 ] != 0 ) { // Is the spec. color black?
@@ -1076,15 +1113,15 @@ SoShape::shouldGLRender(SoGLRenderAction * action)
10761113 SoViewingMatrixElement::get (state);
10771114 m = m.inverse ();
10781115 m.multLeft (lm);
1079- PRIVATE (this )->bumprender ->renderBumpSpecular (state, PRIVATE (this )->pvcache ,
1116+ PRIVATE (shape )->bumprender ->renderBumpSpecular (state, PRIVATE (shape )->pvcache ,
10801117 (SoLight*) lights[i], m);
10811118 }
10821119 }
10831120
10841121 }
10851122
10861123
1087- PRIVATE (this )->unlock ();
1124+ PRIVATE (shape )->unlock ();
10881125
10891126 glPopAttrib ();
10901127 // we used two units in the bumpmap code
@@ -1101,9 +1138,9 @@ SoShape::shouldGLRender(SoGLRenderAction * action)
11011138
11021139 if (shapestyleflags & SoShapeStyleElement::VERTEXARRAY ) {
11031140 // lock since pvcache is shared among all threads
1104- PRIVATE (this )->lock ();
1105- this ->validatePVCache (action);
1106- PRIVATE (this )->unlock ();
1141+ PRIVATE (shape )->lock ();
1142+ shape ->validatePVCache (action);
1143+ PRIVATE (shape )->unlock ();
11071144
11081145 SoGLCacheContextElement::shouldAutoCache (state,
11091146 SoGLCacheContextElement::DONT_AUTO_CACHE );
@@ -1114,18 +1151,18 @@ SoShape::shouldGLRender(SoGLRenderAction * action)
11141151 if (glimage) arrays |= SoPrimitiveVertexCache::TEXCOORD ;
11151152 SoMaterialBundle mb (action);
11161153 mb.sendFirst ();
1117- PRIVATE (this )->setupShapeHints (this , state);
1118- PRIVATE (this )->pvcache ->renderTriangles (state, arrays);
1119- if (PRIVATE (this )->pvcache ->getNumLineIndices () ||
1120- PRIVATE (this )->pvcache ->getNumPointIndices ()) {
1154+ PRIVATE (shape )->setupShapeHints (shape , state);
1155+ PRIVATE (shape )->pvcache ->renderTriangles (state, arrays);
1156+ if (PRIVATE (shape )->pvcache ->getNumLineIndices () ||
1157+ PRIVATE (shape )->pvcache ->getNumPointIndices ()) {
11211158 const SoNormalElement * nelem = SoNormalElement::getInstance (state);
11221159 if (nelem->getNum () == 0 ) {
11231160 glPushAttrib (GL_LIGHTING_BIT );
11241161 glDisable (GL_LIGHTING );
11251162 arrays &= SoPrimitiveVertexCache::NORMAL ;
11261163 }
1127- PRIVATE (this )->pvcache ->renderLines (state, arrays);
1128- PRIVATE (this )->pvcache ->renderPoints (state, arrays);
1164+ PRIVATE (shape )->pvcache ->renderLines (state, arrays);
1165+ PRIVATE (shape )->pvcache ->renderPoints (state, arrays);
11291166
11301167 if (nelem->getNum () == 0 ) {
11311168 glPopAttrib ();
@@ -1139,11 +1176,11 @@ SoShape::shouldGLRender(SoGLRenderAction * action)
11391176 SoMaterialBundle mb (action);
11401177 mb.sendFirst ();
11411178 soshape_get_staticdata ()->currentbundle = &mb; // needed in the primitive callbacks
1142- this ->generatePrimitives (action);
1179+ shape ->generatePrimitives (action);
11431180 return FALSE ;
11441181#else // generatePrimitives() rendering
1145- if (PRIVATE (this )->rendercnt < ((1 <<SoShapeP::RENDERCNT_BITS )-1 )) {
1146- PRIVATE (this )->rendercnt ++;
1182+ if (PRIVATE (shape )->rendercnt < ((1 <<SoShapeP::RENDERCNT_BITS )-1 )) {
1183+ PRIVATE (shape )->rendercnt ++;
11471184 }
11481185 return TRUE ; // let the shape node render the geometry using OpenGL
11491186#endif // ! generatePrimitives() rendering
0 commit comments