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);
|
|||
|
}
|