DYTSrouce/src/effects/ConeWave.cpp

153 lines
4.4 KiB
C++

#include "effects/ConeWave.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 <osg/Depth>
#include <osgEarth/Registry>
ConeWave::ConeWave() {
osgEarth::Registry::shaderGenerator().run(this);
}
ConeWave::~ConeWave(void)
{
}
void ConeWave::Render(double dt) {
}
void ConeWave::InitGeode() {
CreateTexturedCone(this);
//getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
//getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
//getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
//setCullingActive(false);
}
void ConeWave::Destory() {
OnDestroy();
}
void ConeWave::SetHeight(float height) {
height_ = height;
if (cone_) {
cone_->setHeight(height_);
}
coneDrawable_->build();
}
void ConeWave::SetRadius(float radius) {
radius_ = radius;
if (cone_) {
cone_->setRadius(radius);
}
coneDrawable_->build();
}
void ConeWave::SetBaseColor(const osg::Vec4& color) {
baseColor_ = color;
if (baseColorUniform_) {
baseColorUniform_->set(color);
}
}
void ConeWave::SetLevelCount(int count) {
levelCount_ = count;
if (levelCountUniform_) {
levelCountUniform_->set(float(levelCount_));
}
}
void ConeWave::SetLevelHeight(float height) {
levelHeight_ = height;
if (levelHeightUniform_) {
levelHeightUniform_->set(levelHeight_);
}
}
void ConeWave::CreateTexturedCone(osg::Geode* geode) {
cone_ = new osg::Cone(osg::Vec3(0, 0, 0.), radius_, height_);
osg::TessellationHints* tesselate = new osg::TessellationHints;
tesselate->setCreateBottom(false);
tesselate->setCreateBackFace(false);
coneDrawable_ = new osg::ShapeDrawable(cone_, tesselate);
geode->addDrawable(coneDrawable_);
//coneDrawable_->setColor(baseColor_);
//osg::StateSet* ss = coneDrawable_->getOrCreateStateSet();
////stateset->setRenderBinDetails(120, "OSGEARTH_SCREEN_SPACE_LAYOUT_BIN");
//ss->setRenderBinDetails(120, "RenderBin");
//osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc();
//ss->setAttributeAndModes(bf, osg::StateAttribute::ON);
//ss->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
//return;
static const char* vertSource = {
"varying vec3 pos;\n"
"void main()\n"
"{\n"
"pos.x=gl_Vertex.x;\n"
"pos.y=gl_Vertex.y;\n"
"pos.z=gl_Vertex.z;\n"
"gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;\n"
"}\n"
};
static const char* fragSource = {
"uniform float num; \n"
"uniform float height; \n"
"uniform vec4 baseColor;\n"
"varying vec3 pos;\n"
"float Alpha = 1.0; \n"
"float f = pos.z;\n"
"uniform float osg_FrameTime;\n"
"void main()\n"
"{\n"
"if (sin(f/height*3.14*2*num+ osg_FrameTime*10) > 0)\n"
"{\n"
" Alpha = 0.8;\n"
"}\n"
"else\n"
"{\n"
" Alpha = 0.3;\n"
"}\n"
" gl_FragColor = vec4(baseColor.rgb, Alpha);\n"
"}\n "
};
osg::ref_ptr<osg::Shader> vertexShader = new osg::Shader(osg::Shader::VERTEX);
vertexShader->setShaderSource(vertSource);
osg::ref_ptr<osg::Shader> fragmentShader = new osg::Shader(osg::Shader::FRAGMENT);
fragmentShader->setShaderSource(fragSource);
osg::StateSet* stateset = coneDrawable_->getOrCreateStateSet();
//stateset->setRenderBinDetails(120, "OSGEARTH_SCREEN_SPACE_LAYOUT_BIN");
stateset->setRenderBinDetails(120, "RenderBin");
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);
baseColorUniform_ = new osg::Uniform("baseColor", baseColor_);
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
stateset->addUniform(baseColorUniform_);
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
stateset->setAttributeAndModes(new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false));
levelCountUniform_ = new osg::Uniform("num", float(levelCount_));
levelHeightUniform_ = new osg::Uniform("height", levelHeight_);
stateset->addUniform(levelCountUniform_);
stateset->addUniform(levelHeightUniform_.get());
}