void HeightFieldDrawable::accept(osg::PrimitiveFunctor& pf) const { // use the cached vertex positions for PrimitiveFunctor operations if (!_geometry) return; if (_vertices.valid()) { pf.setVertexArray(_vertices->size(), &((*_vertices)[0])); const osg::DrawElementsUShort* deus = dynamic_cast<const osg::DrawElementsUShort*>(_geometry->getDrawElements()); if (deus) { pf.drawElements(GL_QUADS, deus->size(), &((*deus)[0])); } else { const osg::DrawElementsUInt* deui = dynamic_cast<const osg::DrawElementsUInt*>(_geometry->getDrawElements()); if (deui) { pf.drawElements(GL_QUADS, deui->size(), &((*deui)[0])); } } } else { _geometry->accept(pf); } }
// Functor supplies triangles to things like IntersectionVisitor, ComputeBoundsVisitor, etc. void TileDrawable::accept(osg::PrimitiveFunctor& f) const { const osg::Vec3Array& verts = *static_cast<osg::Vec3Array*>(_geom->getVertexArray()); const osg::Vec3Array& normals = *static_cast<osg::Vec3Array*>(_geom->getNormalArray()); #if 1 // triangles (OSG-stats-friendly) //TODO: improve by caching the entire Vec3f, not just the height. f.begin(GL_TRIANGLES); for(int t=0; t<_tileSize-1; ++t) { for(int s=0; s<_tileSize-1; ++s) { int i00 = t*_tileSize + s; int i10 = i00 + 1; int i01 = i00 + _tileSize; int i11 = i01 + 1; osg::Vec3d v01 = verts[i01] + normals[i01] * _heightCache[i01]; osg::Vec3d v10 = verts[i10] + normals[i10] * _heightCache[i10]; f.vertex( verts[i00] + normals[i00] * _heightCache[i00] ); f.vertex( v01 ); f.vertex( v10 ); f.vertex( v10 ); f.vertex( v01 ); f.vertex( verts[i11] + normals[i11] * _heightCache[i11] ); } } f.end(); #else // triangle-strips (faster? but not stats-friendly; will cause the OSG stats // to report _tileSize-1 primitive sets per TileDrawable even though there // is only one. for(int t=0; t<_tileSize-1; ++t) { f.begin( GL_TRIANGLE_STRIP ); for(int s=0; s<_tileSize; ++s) { int i = t*_tileSize + s; f.vertex( verts[i] + normals[i] * _heightCache[i] ); i += _tileSize; f.vertex( verts[i] + normals[i] * _heightCache[i] ); } f.end(); } #endif }
void TileDrawable::accept(osg::PrimitiveFunctor& f) const { if ( !_elevationRaster.valid() ) return; const osg::Vec3Array* verts = static_cast<osg::Vec3Array*>(_geom->getVertexArray()); const osg::Vec3Array* normals = static_cast<osg::Vec3Array*>(_geom->getNormalArray()); ImageUtils::PixelReader elevation(_elevationRaster.get()); float scaleU = _elevationScaleBias(0,0), scaleV = _elevationScaleBias(1,1), biasU = _elevationScaleBias(3,0), biasV = _elevationScaleBias(3,1); for(int t=0; t<_tileSize-1; ++t) { float v = (float)t / (float)(_tileSize-1); float v1 = (float)(t+1) / (float)(_tileSize-1); f.begin( GL_QUAD_STRIP ); for(int s=0; s<_tileSize; ++s) { float u = (float)s / (float)(_tileSize-1); int index = t*_tileSize + s; { const osg::Vec3f& vert = (*verts)[index]; const osg::Vec3f& normal = (*normals)[index]; float h = elevation(u*scaleU+biasU, v*scaleV+biasV).r(); f.vertex( vert + normal*h ); } index += _tileSize; { const osg::Vec3f& vert = (*verts)[index]; const osg::Vec3f& normal = (*normals)[index]; float h = elevation(u*scaleU+biasU, v1*scaleV+biasV).r(); f.vertex( vert + normal*h ); } } f.end(); } }
void Text3D::accept(osg::PrimitiveFunctor& pf) const { // ** for each line, do ... TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) { // ** for each glyph in the line, do ... LineRenderInfo::const_iterator it, end = itLine->end(); for (it = itLine->begin(); it!=end; ++it) { pf.setVertexArray(it->_glyph->getVertexArray()->size(),&(it->_glyph->getVertexArray()->front())); // ** render the front face of the glyph osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr) { (*itr)->accept(pf); } // ** render the wall face of the glyph osg::Geometry::PrimitiveSetList & pslWall = it->_glyph->getWallPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr) { (*itr)->accept(pf); } // ** render the back face of the glyph osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr) { (*itr)->accept(pf); } } } }
// Functor supplies triangles to things like IntersectionVisitor, ComputeBoundsVisitor, etc. void TileDrawable::accept(osg::PrimitiveFunctor& f) const { #if 1 // triangles (OSG-stats-friendly) //TODO: improve by caching the entire Vec3f, not just the height. f.begin(GL_TRIANGLES); for(int t=0; t<_tileSize-1; ++t) { for(int s=0; s<_tileSize-1; ++s) { int i00 = t*_tileSize + s; int i10 = i00 + 1; int i01 = i00 + _tileSize; int i11 = i01 + 1; f.vertex(_mesh[i00]); f.vertex(_mesh[i01]); f.vertex(_mesh[i10]); f.vertex(_mesh[i10]); f.vertex(_mesh[i01]); f.vertex(_mesh[i11]); } } f.end(); #else // triangle-strips (faster? but not stats-friendly; will cause the OSG stats // to report _tileSize-1 primitive sets per TileDrawable even though there // is only one. for(int t=0; t<_tileSize-1; ++t) { f.begin( GL_TRIANGLE_STRIP ); for(int s=0; s<_tileSize; ++s) { int i = t*_tileSize + s; f.vertex( _mesh[i] ); i += _tileSize; f.vertex( _mesh[i] ); } f.end(); } #endif }
void TileDrawable::accept(osg::PrimitiveFunctor& f) const { const osg::Vec3Array* verts = static_cast<osg::Vec3Array*>(_geom->getVertexArray()); const osg::Vec3Array* normals = static_cast<osg::Vec3Array*>(_geom->getNormalArray()); if ( _elevationRaster.valid() ) { ImageUtils::PixelReader elevation(_elevationRaster.get()); elevation.setBilinear(true); float scaleU = _elevationScaleBias(0,0), scaleV = _elevationScaleBias(1,1), biasU = _elevationScaleBias(3,0), biasV = _elevationScaleBias(3,1); //float // texelScale = (float)(_elevationRaster->s()-1)/(float)_elevationRaster->s(), // texelBias = 0.5f/(float)(_elevationRaster->s()); if ( osg::equivalent(scaleU, 0.0f) || osg::equivalent(scaleV, 0.0f) ) { OE_WARN << LC << "Precision loss in tile " << _key.str() << "\n"; } for(int t=0; t<_tileSize-1; ++t) { float v0 = (float)t / (float)(_tileSize-1); float v1 = (float)(t+1) / (float)(_tileSize-1); v0 = v0*scaleV + biasV; v1 = v1*scaleV + biasV; f.begin( GL_QUAD_STRIP ); for(int s=0; s<_tileSize; ++s) { float u = (float)s / (float)(_tileSize-1); u = u*scaleU + biasU; int index = t*_tileSize + s; { const osg::Vec3f& vert = (*verts)[index]; const osg::Vec3f& normal = (*normals)[index]; float h = elevation(u, v0).r(); f.vertex( vert + normal*h ); } index += _tileSize; { const osg::Vec3f& vert = (*verts)[index]; const osg::Vec3f& normal = (*normals)[index]; float h = elevation(u, v1).r(); f.vertex( vert + normal*h ); } } f.end(); } } // no elevation else { for(int t=0; t<_tileSize-1; ++t) { f.begin( GL_QUAD_STRIP ); for(int s=0; s<_tileSize; ++s) { int index = t*_tileSize + s; f.vertex( (*verts)[index] ); f.vertex( (*verts)[index + _tileSize] ); } f.end(); } } }
void SharedGeometry::accept(osg::PrimitiveFunctor& pf) const { pf.setVertexArray(_vertexArray->getNumElements(),static_cast<const osg::Vec3*>(_vertexArray->getDataPointer())); _drawElements->accept(pf); }
void ImpostorSprite::accept(osg::PrimitiveFunctor& functor) const { functor.setVertexArray(4,_coords); functor.drawArrays( GL_QUADS, 0, 4); }