#include "effects/DashedLine.h" #include #include #include #include #include #include #include #include #include #include #include "viewer/OsgViewer.h" DashedLine::DashedLine(const std::string& path) : txturePath_(path) { } DashedLine::~DashedLine(void) { } void DashedLine::Render(double dt) { if (timeUniform_) { timeUniform_->set(static_cast(dt * 0.1)); } } void DashedLine::InitGeode() { osg::ref_ptr geode = new osg::Geode; addChild(geode); CreateTexturedCone(geode); } void DashedLine::Destory() { OnDestroy(); } void DashedLine::SetStart(const osg::Vec3& start) { if (start == start_) { return; } start_ = start; UpdateRotaion(); } void DashedLine::SetEnd(const osg::Vec3& end) { if (end == end_) { return; } end_ = end; UpdateRotaion(); } void DashedLine::SetForward(const osg::Vec3& start, const osg::Vec3& end) { if (start == start_ && end == end_) { return; } start_ = start; end_ = end; UpdateRotaion(); } void DashedLine::SetRadius(float radius) { if (radius == radius_) { return; } radius_ = radius; if (cylinder_) { cylinder_->setRadius(radius); } UpdateRotaion(); } void DashedLine::SetBaseColor(const osg::Vec4& color) { baseColor_ = color; if (baseColorUniform_) { baseColorUniform_->set(color); } } void DashedLine::CreateTexturedCone(osg::Geode* geode) { cylinder_ = new osg::Cylinder(osg::Vec3(0.0f, 0.0f, 0.0f), radius_, 1.0f); cylinderDrawable_ = new osg::ShapeDrawable(cylinder_); geode->addDrawable(cylinderDrawable_); osg::Texture2D* texture = new osg::Texture2D; texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); osg::Image* image = osgDB::readImageFile(txturePath_); texture->setImage(image); osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); vertexShader->setShaderSource( "#version 330\n" "in vec4 osg_Vertex;\n" "in vec2 osg_MultiTexCoord0;\n" "uniform mat4 osg_ModelViewProjectionMatrix;\n"//当前OSG摄像机的观察矩阵; "uniform float time;\n" "out vec2 texCoord;\n" "void main()\n" "{\n" " gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n" " texCoord = osg_MultiTexCoord0 + vec2(0.0, time);\n" "}\n" ); osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); fragmentShader->setShaderSource( "#version 330\n" "in vec2 texCoord;\n" "uniform sampler2D texture;\n" "uniform vec4 baseColor;\n" "out vec4 fragColor;\n" "void main()\n" "{\n" " vec4 color = texture2D(texture, texCoord);\n" " fragColor = clamp(texture2D(texture, texCoord) * baseColor + vec4(0,0,0, 0.2), 0.0, 1.0);\n" "}\n" ); osg::StateSet* stateset = cylinderDrawable_->getOrCreateStateSet(); stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); osg::ref_ptr blendFunc = new osg::BlendFunc(); stateset->setAttributeAndModes(blendFunc, osg::StateAttribute::ON); osg::ref_ptr program = new osg::Program(); program->addShader(vertexShader); program->addShader(fragmentShader); stateset->addUniform(new osg::Uniform("texture", 0)); baseColorUniform_ = new osg::Uniform("baseColor", baseColor_); stateset->addUniform(baseColorUniform_); stateset->setAttributeAndModes(program, osg::StateAttribute::ON); timeUniform_ = new osg::Uniform("time", 0.0f); stateset->addUniform(timeUniform_); UpdateRotaion(); } void DashedLine::UpdateRotaion() { osg::Vec3 direction = end_ - start_; float height = direction.length(); cylinder_->setHeight(height); cylinderDrawable_->build(); osg::Vec3 center = (start_ + end_) * 0.5f; direction.normalize(); setPosition(center); osg::Vec3 up(0.0f, 0.0f, 1.0f); osg::Quat rotation; rotation.makeRotate(up, direction); setAttitude(rotation); }