相关资料:
https://www.jianshu.com/p/6c37c4334c8f OSG仿真案例(4)——创建烟雾粒子效果
代码实例:
.pro
1 QT += core gui widgets 2 TARGET = TestOsgQt 3 TEMPLATE = app 4 DEFINES += QT_DEPRECATED_WARNINGS 5 CONFIG += c++11 6 7 SOURCES += \ 8 main.cpp 9 10 HEADERS += 11 12 OsgDir = D:\\RuanJian\\osg365R 13 CONFIG(release, debug|release) { 14 LIBS += -L$${OsgDir}/lib/ -losgDB -losgViewer -lOpenThreads -losgAnimation -losg \ 15 -losgEarth -losgEarthAnnotation -losgEarthFeatures -losgEarthSymbology -losgEarthUtil \ 16 -losgQOpenGL -losgUtil -losgText -losgTerrain -losgSim \ 17 -losgShadow -losgParticle -losgManipulator -losgGA -losgFX \ 18 -losgWidget 19 } else { 20 LIBS += -L$${OsgDir}/debug/lib/ -losgDBd -losgViewerd -lOpenThreadsd -losgAnimationd -losgd \ 21 -losgEarthd -losgEarthAnnotationd -losgEarthFeaturesd -losgEarthSymbologyd -losgEarthUtild \ 22 -losgQOpenGLd -losgUtild -losgTextd -losgTerraind -losgSimd \ 23 -losgShadowd -losgParticled -losgManipulatord -losgGAd -losgFXd \ 24 } 25 26 27 INCLUDEPATH += $${OsgDir}/include 28 DEPENDPATH += $${OsgDir}/include
main.cpp
1 #include <QApplication> 2 3 #include <osg/Node> 4 #include <osg/Group> 5 #include <osg/Geode> 6 #include <osg/Geometry> 7 #include <osg/Texture2D> 8 #include <osg/StateSet> 9 #include <osg/PositionAttitudeTransform> 10 #include <osgViewer/Viewer> 11 #include <osgDB/ReadFile> 12 #include <osgParticle/PrecipitationEffect> 13 // 雨雪效果 14 #include <osg/MatrixTransform> 15 // 粒子效果 16 #include <osgParticle/PrecipitationEffect> 17 #include <osgParticle/Particle> 18 #include <osgParticle/LinearInterpolator> 19 #include <osgParticle/ParticleSystem> 20 #include <osgParticle/RandomRateCounter> 21 #include <osgParticle/PointPlacer> 22 #include <osgParticle/RadialShooter> 23 #include <osgParticle/ModularEmitter> 24 #include <osgParticle/ParticleSystemUpdater> 25 #include <osgParticle/ModularProgram> 26 #include <osgUtil/Optimizer> 27 #include <osgUtil/Simplifier> 28 // 雾 29 #include <osg/Fog> 30 #include <osgDB/ReadFile> 31 #include <osgViewer/Viewer> 32 #include <osg/StateSet> 33 #include <osg/StateAttribute> 34 #include <osgViewer/ViewerEventHandlers> 35 #include <osgWidget/ViewerEventHandlers> 36 37 //创建火球(燃烧) 38 void createFireBall(osg::MatrixTransform *smokeNode) 39 { 40 // 创建粒子对象,设置其属性并交由粒子系统使用。 41 osgParticle::Particle particleTempalte; 42 particleTempalte.setShape(osgParticle::Particle::QUAD); 43 particleTempalte.setLifeTime(1.5); // 单位:秒 44 particleTempalte.setSizeRange(osgParticle::rangef(3.0f, 1.0f)); // 单位:米 45 particleTempalte.setAlphaRange(osgParticle::rangef(1, 0)); 46 particleTempalte.setColorRange(osgParticle::rangev4(osg::Vec4(1.0f, 0.2f, 0.0f, 1.0f),//0.1f,0.3f,0.4f,1.0f 47 osg::Vec4(0.1f, 0.1f, 0.1f, 0)//0.95f,0.75f,0,1(1,1,1,1) 48 )); 49 particleTempalte.setPosition(osg::Vec3(0.0f, 0.0f, 0.0f)); 50 particleTempalte.setVelocity(osg::Vec3(0.0f, 0.0f, 0.0f)); 51 particleTempalte.setMass(0.1f); //单位:千克 52 particleTempalte.setRadius(0.2f); 53 particleTempalte.setSizeInterpolator(new osgParticle::LinearInterpolator); 54 particleTempalte.setAlphaInterpolator(new osgParticle::LinearInterpolator); 55 particleTempalte.setColorInterpolator(new osgParticle::LinearInterpolator); 56 // 创建并初始化粒子系统。 57 osgParticle::ParticleSystem *particleSystem = new osgParticle::ParticleSystem; 58 particleSystem->setDataVariance(osg::Node::STATIC); 59 // 设置材质,是否放射粒子,以及是否使用光照。 60 particleSystem->setDefaultAttributes("G:\\YCThirdParty\\Osg\\data\\Images\\smoke.rgb", true, false); 61 osg::Geode *geode = new osg::Geode; 62 geode->addDrawable(particleSystem); 63 smokeNode->addChild(geode); 64 //设置为粒子系统的缺省粒子对象。 65 particleSystem->setDefaultParticleTemplate(particleTempalte); 66 //获取放射极中缺省计数器的句柄,调整每帧增加的新粒子数目 67 osgParticle::RandomRateCounter *particleGenerateRate = new osgParticle::RandomRateCounter(); 68 particleGenerateRate->setRateRange(30, 50); 69 // 每秒新生成的粒子范围 70 particleGenerateRate->setDataVariance(osg::Node::DYNAMIC); 71 // 自定义一个放置器,这里创建并初始化一个点放置器 72 osgParticle::PointPlacer * particlePlacer = new osgParticle::PointPlacer; 73 particlePlacer->setCenter(osg::Vec3(0.0f, 0.0f, 0.0f)); 74 particlePlacer->setDataVariance(osg::Node::DYNAMIC); 75 // 自定义一个弧度发射器 76 osgParticle::RadialShooter* particleShooter = new osgParticle::RadialShooter; 77 // 设置发射器的属性 78 particleShooter->setDataVariance(osg::Node::DYNAMIC); 79 particleShooter->setThetaRange(-0.1f, 0.1f); 80 // 弧度值,与Z 轴夹角 81 particleShooter->setPhiRange(-0.1f, 0.1f); 82 particleShooter->setInitialSpeedRange(5, 7.5f);//单位:米/秒 83 //创建标准放射极对象 84 osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter; 85 emitter->setDataVariance(osg::Node::DYNAMIC); 86 emitter->setCullingActive(false); 87 // 将放射极对象与粒子系统关联。 88 emitter->setParticleSystem(particleSystem); 89 // 设置计数器 90 emitter->setCounter(particleGenerateRate); 91 // 设置放置器 92 emitter->setPlacer(particlePlacer); 93 // 设置发射器 94 emitter->setShooter(particleShooter); 95 // 把放射极添加为变换节点 96 smokeNode->addChild(emitter); 97 // 添加更新器,以实现每帧的粒子管理。 98 osgParticle::ParticleSystemUpdater *particleSystemUpdater = new osgParticle::ParticleSystemUpdater; 99 // 将更新器与粒子系统对象关联。 100 particleSystemUpdater->addParticleSystem(particleSystem); 101 // 将更新器节点添加到场景中。 102 smokeNode->addChild(particleSystemUpdater); 103 // 创建标准编程器对象并与粒子系统相关联。 104 osgParticle::ModularProgram *particleMoveProgram = new osgParticle::ModularProgram; 105 particleMoveProgram->setParticleSystem(particleSystem); 106 // 最后,将编程器添加到场景中。 107 smokeNode->addChild(particleMoveProgram); 108 } 109 110 //创建浓烟 111 void createDarkSmoke(osg::MatrixTransform *smokeNode) 112 { 113 // 创建粒子对象,设置其属性并交由粒子系统使用。 114 osgParticle::Particle particleTempalte; 115 particleTempalte.setShape(osgParticle::Particle::QUAD); 116 particleTempalte.setLifeTime(10); // 单位:秒 117 particleTempalte.setSizeRange(osgParticle::rangef(1.0f, 12.0f)); // 单位:米 118 particleTempalte.setAlphaRange(osgParticle::rangef(1, 0)); 119 particleTempalte.setColorRange(osgParticle::rangev4( 120 osg::Vec4(0.0f, 0.0f, 0.0f, 0.5f),//(0.1f,0.1f,0.1f,0.5f) 121 osg::Vec4(0.5f, 0.5f, 0.5f, 1.5f)//0.95f,0.75f,0,1 122 )); 123 particleTempalte.setPosition(osg::Vec3(0.0f, 0.0f, 0.0f)); 124 particleTempalte.setVelocity(osg::Vec3(0.0f, 0.0f, 0.0f)); 125 particleTempalte.setMass(0.1f); //单位:千克 126 particleTempalte.setRadius(0.2f); 127 particleTempalte.setSizeInterpolator(new osgParticle::LinearInterpolator); 128 particleTempalte.setAlphaInterpolator(new osgParticle::LinearInterpolator); 129 particleTempalte.setColorInterpolator(new osgParticle::LinearInterpolator); 130 // 创建并初始化粒子系统。 131 osgParticle::ParticleSystem *particleSystem = new osgParticle::ParticleSystem; 132 particleSystem->setDataVariance(osg::Node::STATIC); 133 // 设置材质,是否放射粒子,以及是否使用光照。 134 particleSystem->setDefaultAttributes("G:\\YCThirdParty\\Osg\\data\\Images\\smoke.rgb", false, false); 135 osg::Geode *geode = new osg::Geode; 136 geode->addDrawable(particleSystem); 137 smokeNode->addChild(geode); 138 //设置为粒子系统的缺省粒子对象。 139 particleSystem->setDefaultParticleTemplate(particleTempalte); 140 //获取放射极中缺省计数器的句柄,调整每帧增加的新粒 141 //子数目 142 osgParticle::RandomRateCounter *particleGenerateRate = new osgParticle::RandomRateCounter(); 143 particleGenerateRate->setRateRange(30, 50); 144 // 每秒新生成的粒子范围 145 particleGenerateRate->setDataVariance(osg::Node::DYNAMIC); 146 // 自定义一个放置器,这里我们创建并初始化一个点放置器 147 osgParticle::PointPlacer * particlePlacer = new osgParticle::PointPlacer; 148 particlePlacer->setCenter(osg::Vec3(0.0f, 0.0f, 0.05f)); 149 particlePlacer->setDataVariance(osg::Node::DYNAMIC); 150 // 自定义一个弧度发射器 151 osgParticle::RadialShooter* particleShooter = new osgParticle::RadialShooter; 152 // 设置发射器的属性 153 particleShooter->setDataVariance(osg::Node::DYNAMIC); 154 particleShooter->setThetaRange(-0.1f, 0.1f); 155 // 弧度值,与Z 轴夹角0.392699f 156 particleShooter->setPhiRange(-0.1f, 0.1f); 157 particleShooter->setInitialSpeedRange(10, 15); 158 //单位:米/秒 159 //创建标准放射极对象 160 osgParticle::ModularEmitter *emitter = new osgParticle:: 161 ModularEmitter; 162 emitter->setDataVariance(osg::Node::DYNAMIC); 163 emitter->setCullingActive(false); 164 // 将放射极对象与粒子系统关联。 165 emitter->setParticleSystem(particleSystem); 166 // 设置计数器 167 emitter->setCounter(particleGenerateRate); 168 // 设置放置器 169 emitter->setPlacer(particlePlacer); 170 // 设置发射器 171 emitter->setShooter(particleShooter); 172 // 把放射极添加为变换节点 173 smokeNode->addChild(emitter); 174 // 添加更新器,以实现每帧的粒子管理。 175 osgParticle::ParticleSystemUpdater *particleSystemUpdater = new osgParticle::ParticleSystemUpdater; 176 // 将更新器与粒子系统对象关联。 177 particleSystemUpdater->addParticleSystem(particleSystem); 178 // 将更新器节点添加到场景中。 179 smokeNode->addChild(particleSystemUpdater); 180 osgParticle::ModularProgram *particleMoveProgram = new osgParticle::ModularProgram; 181 particleMoveProgram->setParticleSystem(particleSystem); 182 // 最后,将编程器添加到场景中。 183 smokeNode->addChild(particleMoveProgram); 184 } 185 186 int main(int argc, char *argv[]) 187 { 188 osg::Group* root = new osg::Group(); 189 // ------------------粒子效果----------------------- 190 osg::MatrixTransform * flightTransform = new osg::MatrixTransform(); 191 root ->addChild(flightTransform); 192 //引擎烟雾 193 osg::MatrixTransform* fireballAndSmoke = new osg::MatrixTransform(); 194 createFireBall(fireballAndSmoke); 195 196 fireballAndSmoke->setMatrix(osg::Matrix::rotate(-osg::PI / 2, 1, 0, 0)*osg::Matrix::translate(-8, -10, -3)); 197 flightTransform->addChild(fireballAndSmoke); 198 createDarkSmoke(fireballAndSmoke); 199 200 osgUtil::Simplifier simplifier(0.3f, 4.0f); 201 osgUtil::Optimizer optimzer; 202 203 optimzer.optimize(root); 204 // ------------------设置窗口------------------ 205 //最后,设置视窗类并进入仿真循环。 206 osgViewer::Viewer viewer; 207 //设置图形环境特性 208 osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits(); 209 traits->x = 100; 210 traits->y = 200; 211 traits->width = 600; 212 traits->height = 500; 213 traits->windowDecoration = true; 214 traits->doubleBuffer = true; 215 traits->sharedContext = 0; 216 //创建图形环境特性 217 osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get()); 218 if (gc.valid()) 219 { 220 osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<<std::endl; 221 222 //清除窗口颜色及清除颜色和深度缓冲 223 gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f)); 224 gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 225 } 226 else 227 { 228 osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<<std::endl; 229 } 230 //设置视口 231 viewer.getCamera()->setViewport(new osg::Viewport(0,0, traits->width, traits->height)); 232 //设置图形环境 233 viewer.getCamera()->setGraphicsContext(gc.get()); 234 viewer.setSceneData( root ); 235 return viewer.run(); 236 }