void PolygonizeLinesOperator::installShaders(osg::Node* node) const { if ( !node ) return; float minPixels = _stroke.minPixels().getOrUse( 0.0f ); if ( minPixels <= 0.0f ) return; osg::StateSet* stateset = node->getOrCreateStateSet(); VirtualProgram* vp = VirtualProgram::getOrCreate(stateset); // bail if already installed. if ( vp->getName().compare( SHADER_NAME ) == 0 ) return; vp->setName( SHADER_NAME ); const char* vs = "#version " GLSL_VERSION_STR "\n" GLSL_DEFAULT_PRECISION_FLOAT "\n" "in vec3 oe_polyline_center; \n" "uniform float oe_polyline_scale; \n" "uniform float oe_polyline_min_pixels; \n" "uniform vec4 oe_PixelSizeVector; \n" "void oe_polyline_scalelines(inout vec4 vertex_model4) \n" "{ \n" " const float epsilon = 0.0001; \n" " vec4 center = vec4(oe_polyline_center, 1.0); \n" " vec3 vector = vertex_model4.xyz - center.xyz; \n" " float r = length(vector); \n" " float activate = step(epsilon, r*oe_polyline_min_pixels);\n" " float pixelSize = max(epsilon, 2.0*abs(r/dot(center, oe_PixelSizeVector))); \n" " float min_scale = max(oe_polyline_min_pixels/pixelSize, 1.0); \n" " float scale = mix(1.0, max(oe_polyline_scale, min_scale), activate); \n" " vertex_model4.xyz = center.xyz + vector*scale; \n" "} \n"; vp->setFunction( "oe_polyline_scalelines", vs, ShaderComp::LOCATION_VERTEX_MODEL, 0.5f ); vp->addBindAttribLocation( "oe_polyline_center", ATTR_LOCATION ); // add the default scaling uniform. // good way to test: // osgearth_viewer earthfile --uniform oe_polyline_scale 1.0 10.0 osg::Uniform* scaleU = new osg::Uniform(osg::Uniform::FLOAT, "oe_polyline_scale"); scaleU->set( 1.0f ); stateset->addUniform( scaleU, 1 ); // the default "min pixels" uniform. osg::Uniform* minPixelsU = new osg::Uniform(osg::Uniform::FLOAT, "oe_polyline_min_pixels"); minPixelsU->set( minPixels ); stateset->addUniform( minPixelsU, 1 ); // this will install and update the oe_PixelSizeVector uniform. node->addCullCallback( new PixelSizeVectorCullCallback(stateset) ); }