一、前言通过使用着色器实现简单的贴地扫描效果基于此效果可以添加线框、刻度盘等。二、效果非贴地贴地三、几何体构建osg::ref_ptrosg::Node EntityRadarScan::BuildEntityBody() { Style circleStyle; //circleStyle.getOrCreatePolygonSymbol()-fill()-color() Color(Color::Cyan, 0.5); circleStyle.getOrCreateAltitudeSymbol()-clamping() AltitudeSymbol::CLAMP_TO_TERRAIN; circleStyle.getOrCreateAltitudeSymbol()-technique() AltitudeSymbol::TECHNIQUE_DRAPE; circle new CircleNode( DigitalEarthWidget::GetInstance()-m_pMapNode.get(), GeoPoint(DigitalEarthWidget::GetInstance()-m_pMapNode-getMapSRS(), m_stLocation.dLng, m_stLocation.dLat, m_stLocation.dAlt, ALTMODE_ABSOLUTE), Distance(m_iRadius, Units::METERS), circleStyle, Angle(0.0, Units::DEGREES), Angle(360.0, Units::DEGREES), true); CreateShaders(*(circle-getOrCreateStateSet())); return circle.get(); }四、着色器代码void EntityRadarScan::InitShaderProgram(QString strVert, QString strFrag)const { strVert \ varying vec2 v_texcoord;\ void main() {\ v_texcoord gl_Vertex.xy;\ gl_Position gl_ModelViewProjectionMatrix * gl_Vertex;\ }; strFrag \ uniform float simTime;\ uniform vec4 baseColor;\ uniform vec4 scanColor;\ varying vec2 v_texcoord;\ const float pi 3.1415926;\n\ void main() {\ vec2 pos normalize(v_texcoord);\n\ // 计算当前角度(0-2π)\n\ float angle atan(pos.y, pos.x)pi;\n\ // 将时间转换为旋转角度(0-2π)\n\ float scanAngle mod(simTime , 2*pi);\n\ // 计算角度差值(0-2π)\n\ float angleDiff mod(angle - scanAngle , 2*pi);\n\ if(angleDiff1.0){\n\ gl_FragColor baseColor;\n\ }else {\n\ gl_FragColor mix(baseColor, scanColor, angleDiff0.0?0.0:angleDiff); \n\ }\n\ }; } void EntityRadarScan::CreateShaders(osg::StateSet ss) { QString m_strVertSource; QString m_strfragSource; InitShaderProgram(m_strVertSource, m_strfragSource); osg::ref_ptrosg::Shader vertShader new osg::Shader(osg::Shader::VERTEX, m_strVertSource.toStdString()); osg::ref_ptrosg::Shader fragShader new osg::Shader(osg::Shader::FRAGMENT, m_strfragSource.toStdString()); osg::ref_ptrosg::Program program new osg::Program; program-addShader(vertShader.get()); program-addShader(fragShader.get()); osg::ref_ptrosg::Uniform simTime new osg::Uniform(simTime, 1.0f); ss.addUniform(simTime.get()); osg::ref_ptrosg::Uniform baseColor new osg::Uniform(baseColor, m_baseColor); ss.addUniform(baseColor.get()); osg::ref_ptrosg::Uniform scanColor new osg::Uniform(scanColor, m_scanColor); ss.addUniform(scanColor.get()); ss.setAttributeAndModes(program.get()); ss.setAttributeAndModes(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); ss.setMode(GL_BLEND, osg::StateAttribute::ON); ss.setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); ss.setRenderingHint(osg::StateSet::TRANSPARENT_BIN); //ss.setRenderBinDetails(99, RenderBin); // 使用更高的渲染顺序 }五、传值驱动bool EntityRadarScan::EntityUpdate(osg::Node* node, osg::NodeVisitor* nv) { setMatrix(GetLocationMatrix()); if (circle) { osg::StateSet* stateset circle-getOrCreateStateSet(); osg::Uniform* simTime stateset-getUniform(simTime); if (simTime) { float alpha (float)(osg::Timer::instance()-time_s())*2.0; //OSG_WARN alpha std::endl; simTime-set(alpha); } } return true; }原创不易记得点赞加关注哦我会持续分享实用的功能:-
osgearth 实现简单的雷达扫描
一、前言通过使用着色器实现简单的贴地扫描效果基于此效果可以添加线框、刻度盘等。二、效果非贴地贴地三、几何体构建osg::ref_ptrosg::Node EntityRadarScan::BuildEntityBody() { Style circleStyle; //circleStyle.getOrCreatePolygonSymbol()-fill()-color() Color(Color::Cyan, 0.5); circleStyle.getOrCreateAltitudeSymbol()-clamping() AltitudeSymbol::CLAMP_TO_TERRAIN; circleStyle.getOrCreateAltitudeSymbol()-technique() AltitudeSymbol::TECHNIQUE_DRAPE; circle new CircleNode( DigitalEarthWidget::GetInstance()-m_pMapNode.get(), GeoPoint(DigitalEarthWidget::GetInstance()-m_pMapNode-getMapSRS(), m_stLocation.dLng, m_stLocation.dLat, m_stLocation.dAlt, ALTMODE_ABSOLUTE), Distance(m_iRadius, Units::METERS), circleStyle, Angle(0.0, Units::DEGREES), Angle(360.0, Units::DEGREES), true); CreateShaders(*(circle-getOrCreateStateSet())); return circle.get(); }四、着色器代码void EntityRadarScan::InitShaderProgram(QString strVert, QString strFrag)const { strVert \ varying vec2 v_texcoord;\ void main() {\ v_texcoord gl_Vertex.xy;\ gl_Position gl_ModelViewProjectionMatrix * gl_Vertex;\ }; strFrag \ uniform float simTime;\ uniform vec4 baseColor;\ uniform vec4 scanColor;\ varying vec2 v_texcoord;\ const float pi 3.1415926;\n\ void main() {\ vec2 pos normalize(v_texcoord);\n\ // 计算当前角度(0-2π)\n\ float angle atan(pos.y, pos.x)pi;\n\ // 将时间转换为旋转角度(0-2π)\n\ float scanAngle mod(simTime , 2*pi);\n\ // 计算角度差值(0-2π)\n\ float angleDiff mod(angle - scanAngle , 2*pi);\n\ if(angleDiff1.0){\n\ gl_FragColor baseColor;\n\ }else {\n\ gl_FragColor mix(baseColor, scanColor, angleDiff0.0?0.0:angleDiff); \n\ }\n\ }; } void EntityRadarScan::CreateShaders(osg::StateSet ss) { QString m_strVertSource; QString m_strfragSource; InitShaderProgram(m_strVertSource, m_strfragSource); osg::ref_ptrosg::Shader vertShader new osg::Shader(osg::Shader::VERTEX, m_strVertSource.toStdString()); osg::ref_ptrosg::Shader fragShader new osg::Shader(osg::Shader::FRAGMENT, m_strfragSource.toStdString()); osg::ref_ptrosg::Program program new osg::Program; program-addShader(vertShader.get()); program-addShader(fragShader.get()); osg::ref_ptrosg::Uniform simTime new osg::Uniform(simTime, 1.0f); ss.addUniform(simTime.get()); osg::ref_ptrosg::Uniform baseColor new osg::Uniform(baseColor, m_baseColor); ss.addUniform(baseColor.get()); osg::ref_ptrosg::Uniform scanColor new osg::Uniform(scanColor, m_scanColor); ss.addUniform(scanColor.get()); ss.setAttributeAndModes(program.get()); ss.setAttributeAndModes(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); ss.setMode(GL_BLEND, osg::StateAttribute::ON); ss.setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); ss.setRenderingHint(osg::StateSet::TRANSPARENT_BIN); //ss.setRenderBinDetails(99, RenderBin); // 使用更高的渲染顺序 }五、传值驱动bool EntityRadarScan::EntityUpdate(osg::Node* node, osg::NodeVisitor* nv) { setMatrix(GetLocationMatrix()); if (circle) { osg::StateSet* stateset circle-getOrCreateStateSet(); osg::Uniform* simTime stateset-getUniform(simTime); if (simTime) { float alpha (float)(osg::Timer::instance()-time_s())*2.0; //OSG_WARN alpha std::endl; simTime-set(alpha); } } return true; }原创不易记得点赞加关注哦我会持续分享实用的功能:-