/* Draw the node by rendering the children. */ void VertexBufferNode::draw( VertexBufferState& state ) const { if ( state.stopRendering( )) return; _left->draw( state ); _right->draw( state ); }
/* Draw the leaf. */ void VertexBufferLeaf::draw( VertexBufferState& state ) const { if ( state.stopRendering( )) return; switch( state.getRenderMode() ) { case RENDER_MODE_IMMEDIATE: renderImmediate( state ); return; case RENDER_MODE_BUFFER_OBJECT: renderBufferObject( state ); return; case RENDER_MODE_DISPLAY_LIST: default: renderDisplayList( state ); return; } }
// #define LOGCULL void VertexBufferRoot::cullDraw( VertexBufferState& state ) const { _beginRendering( state ); #ifdef LOGCULL size_t verticesRendered = 0; size_t verticesOverlap = 0; #endif const Range& range = state.getRange(); FrustumCuller culler; culler.setup( state.getProjectionModelViewMatrix( )); // start with root node std::vector< const mesh::VertexBufferBase* > candidates; candidates.push_back( this ); while( !candidates.empty() ) { if( state.stopRendering( )) return; const mesh::VertexBufferBase* treeNode = candidates.back(); candidates.pop_back(); // completely out of range check if( treeNode->getRange()[0] >= range[1] || treeNode->getRange()[1] < range[0] ) { continue; } // bounding sphere view frustum culling const vmml::Visibility visibility = state.useFrustumCulling() ? culler.test_sphere( treeNode->getBoundingSphere( )) : vmml::VISIBILITY_FULL; switch( visibility ) { case vmml::VISIBILITY_FULL: // if fully visible and fully in range, render it if( treeNode->getRange()[0] >= range[0] && treeNode->getRange()[1] < range[1] ) { treeNode->draw( state ); //treeNode->drawBoundingSphere( state ); #ifdef LOGCULL verticesRendered += treeNode->getNumberOfVertices(); #endif break; } // partial range, fall through to partial visibility case vmml::VISIBILITY_PARTIAL: { const mesh::VertexBufferBase* left = treeNode->getLeft(); const mesh::VertexBufferBase* right = treeNode->getRight(); if( !left && !right ) { if( treeNode->getRange()[0] >= range[0] ) { treeNode->draw( state ); //treeNode->drawBoundingSphere( state ); #ifdef LOGCULL verticesRendered += treeNode->getNumberOfVertices(); if( visibility == vmml::VISIBILITY_PARTIAL ) verticesOverlap += treeNode->getNumberOfVertices(); #endif } // else drop, to be drawn by 'previous' channel } else { if( left ) candidates.push_back( left ); if( right ) candidates.push_back( right ); } break; } case vmml::VISIBILITY_NONE: // do nothing break; } } _endRendering( state ); #ifdef LOGCULL const size_t verticesTotal = model->getNumberOfVertices(); MESHINFO << getName() << " rendered " << verticesRendered * 100 / verticesTotal << "% of model, overlap <= " << verticesOverlap * 100 / verticesTotal << "%" << std::endl; #endif }