166 lines
4.5 KiB
C++
166 lines
4.5 KiB
C++
#include "effects/DashedLine.h"
|
||
|
||
#include <osg/BlendFunc>
|
||
#include <osg/Material>
|
||
#include <osg/Texture2D>
|
||
#include <osg/ShapeDrawable>
|
||
#include <osg/Group>
|
||
#include <osgViewer/Viewer>
|
||
#include <osgDB/ReadFile>
|
||
#include <osg/Shader>
|
||
#include <osg/Program>
|
||
#include <osg/Uniform>
|
||
|
||
#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<float>(dt * 0.1));
|
||
}
|
||
}
|
||
|
||
void DashedLine::InitGeode() {
|
||
osg::ref_ptr<osg::Geode> 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<osg::Shader> 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"//<2F><>ǰOSG<53><47><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ۲<C4B9><DBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
"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<osg::Shader> 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<osg::BlendFunc> blendFunc = new osg::BlendFunc();
|
||
stateset->setAttributeAndModes(blendFunc, osg::StateAttribute::ON);
|
||
osg::ref_ptr<osg::Program> 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);
|
||
}
|