Irrlicht学习笔记(8)--SpecialFX
2016-07-04 21:29
246 查看
说明:
本例程介绍:阴影
粒子系统
布告板
动态光照
水面节点
1.载入一个房间
用于表现动态光照关键步骤为;1.1,1.3. 1.2是为了优化贴图效果
//1.加载一个房间模型
1.1加载模型网格
scene::IAnimatedMesh* mesh = smgr->getMesh("../media/room.3ds");1.2可选:获得网格控制器
//旋转,缩放,颜色设置,透明度设置,反转表面,诸如此类scene::IMeshManipulator* meshman = smgr->getMeshManipulator();
//在网格上创建平铺的纹理图,优化贴图效果
meshman->makePlanarTextureMapping(mesh->getMesh(0), 0.004f);
1.3
scene::ISceneNode* node = 0;//创建场景节点node = smgr->addAnimatedMeshSceneNode(mesh);//将网格加载到场景节点
node->setMaterialTexture(0, driver->getTexture("../media/wall.jpg"));//设置节点纹理
node->getMaterial(0).SpecularColor.set(0, 0, 0, 0);//
2.第一个特殊效果:水波
工作原理:
WaterSurfaceSceneNode接受一个输入mesh,使之像水面一样扰动.还可以为它添加材质,反射效果.
至于mesh,使用Irrlicht内部方法创建一个山作为表面网格,也可以是其他任何网格,比如上面的room.3ds
mesh = smgr->addHillPlaneMesh(
"Hill",//名字,用于获取这个生成的网格:smgr->getMesh()
core::dimension2d<f32>(20,20),//titlesize,尺寸
core::dimension2d<u32>(40,40),//titlecount,制定title的数量
0,//irr::video::SMaterial
0,//hillheight
core::dimension2d<f32>(10,10),//counthills
core::dimension2d<f32>(1.0,1.0)//textureRepeatCount,纹理重复次数
);
想要看到生成的hill,可以绑定到一个动画网格节点,并设置相关材质.
创建水波节点
将hill网格绑定到水面节点.node = smgr->addWaterSurfaceSceneNode(
mesh->getMesh(0),//irr::IMesh*
3.0f,//waveheight
300,//wavespeed
30.0f//wavelength
//0,//parent
//-1,//id
//core::vector3df(0, 7, 0),//position
//core::vector3df(0, 0, 0),//rotation
//core::vector3df(1.0f, 1.0f, 1.0f)//scale
);
设置水面节点的属性
石头和水面纹理分别设置为0,1层纹理,并设置反射//位置,材质,以及材质属性
node->setPosition(core::vector3df(0, 10, 0));
node->setMaterialTexture(0, driver->getTexture("../media/stones.jpg"));
node->setMaterialTexture(1, driver->getTexture("../media/water.jpg"));
node->setMaterialType(video::EMT_REFLECTION_2_LAYER);
3.布告板和移动光源
建立一个光源,绑定一个移动动画,再绑定一个布告板//将布告板绑定到动态移动的光源
3.1创建一个灯光节点
node = smgr->addLightSceneNode(0, //parent
core::vector3df(0, 0, 0),//position
video::SColorf(1.0f, 0.6f, 0.7f, 1.0f),//rgba:0-1
700,//radius
-1//id
);
3.2创建一个动画,并绑定到灯光节点
scene::ISceneNodeAnimator* anim =smgr->createFlyCircleAnimator(
core::vector3df(0, 150, 0),//center
250,//radius
0.001,//speed
core::vector3df(0,1,0),//position方向
0.0,//startPosition
0.0//radiusEllipsoid
);
node->addAnimator(anim);
anim->drop();
3.3绑定一个布告板,并初始化布告板的属性:材质,颜色,透明度
node = smgr->addBillboardSceneNode(node,//parent,绑定到灯光节点
core::dimension2d<f32>(50,50)//size
);
node->setMaterialFlag(video::EMF_LIGHTING, false);//关闭布告板的光照属性
node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
node->setMaterialTexture(0, driver->getTexture("../media/particlewhite.bmp"));
4.粒子系统
关键:粒子发射器(Emitter),粒子控制器(Affector)粒子系统在Irrlicht引擎中被高度模块化,可扩展性强,使用方便
粒子系统场景节点用于管理,
加入粒子发射器,
加入粒子控制器
例子发射器有很多种,若不满意,可以自己扩展:
1创建一个类,继承IParticleEmitter接口
2绑定自己的发射器到粒子系统,setEmitter()
本例创建一个box粒子发射器:在一个盒子内随机生成粒子
参数:方向,范围,频率,存活时间
粒子控制器用于模拟外界对粒子的影响,比如重力和风
本例只影响颜色
粒子控制器也可以自己定义,
1自定义类,继承IParticleAffector
2绑定到粒子系统,addAffector()
创建好粒子系统,设置材质,纹理,发射器,控制器,可以模拟大量效果,比如烟雾,雨等
4.1创建粒子系统
scene::IParticleSystemSceneNode* ps =smgr->addParticleSystemSceneNode(
false//是否带默认发射器
);
4.2创建粒子发射器
scene::IParticleEmitter* em = ps->createBoxEmitter(core::aabbox3df(-7, 0, -7, 7, 1, 7),//发射器盒子范围
core::vector3df(0, 0.06, 0),//方向
20,//最小发射速度
100,//最大速度
video::SColor(0, 255, 255, 255),//最深的颜色
video::SColor(0, 255, 255, 255),//最亮的颜色
200,//最短存活时间
2000,//最长存活时间
0,//最大角度
core::dimension2df(10, 10),//最小尺寸
core::dimension2df(20, 20)//最大尺寸
);
//绑定
ps->setEmitter(em);
em->drop();
4.3创建粒子控制器
//此处没有用到scene::IParticleAffector* paf = ps->createFadeOutParticleAffector();
ps->addAffector(paf);
paf->drop();
4.4设置粒子系统
ps->setPosition(core::vector3df(-70, 60, 40));ps->setScale(core::vector3df(2, 2, 2));
ps->setMaterialFlag(video::EMF_LIGHTING, false);
ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
ps->setMaterialTexture(0, driver->getTexture("../media/fire.bmp"));
ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);
5.创建一个空间灯光节点
scene::IVolumeLightSceneNode* n = smgr->addVolumeLightSceneNode(0,//parent
-1,//id
32,//sub u
32,//sub v
video::SColor(0, 255, 255, 255),//foot color
video::SColor(0, 0, 0, 0)//tail color
);
//设置属性
if (n)
{
n->setScale(core::vector3df(56, 56, 56));
n->setPosition(core::vector3df(-120, 50, 40));
//n->setMaterialFlag(video::EMF_LIGHTING, false);
//创建一个动画,由7张连续图片组成
core::array<video::ITexture*> textures;
for (s32 g = 7; g > 0; --g)
{
core::stringc tmp;
tmp = "../media/portal";
tmp += g;
tmp += ".bmp";
video::ITexture* t = driver->getTexture(tmp.c_str());
textures.push_back(t);
}
//创建动画
scene::ISceneNodeAnimator* glow = smgr->createTextureAnimator(
textures,//
150,//每帧的时间
true//loop
);
n->addAnimator(glow);
glow->drop();
}
6.动态阴影
//创建一个动画模型投射出阴影,6.1创建动画节点
mesh = smgr->getMesh("../media/dwarf.x");scene::IAnimatedMeshSceneNode* anode = 0;
anode = smgr->addAnimatedMeshSceneNode(mesh);
anode->setPosition(core::vector3df(-50, 20, -60));
anode->setAnimationSpeed(15);
6.2增加阴影
anode->addShadowVolumeSceneNode();smgr->setShadowColor(video::SColor(150, 0, 0, 0));//全局的
6.3设置
//放大模型,随后需要重新单位化法向量anode->setScale(core::vector3df(2, 2, 2));
anode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
代码
#include <iostream> #include <irrlicht.h> using namespace irr; #ifdef _IRR_WINDOWS_ #pragma comment(lib, "irrlicht.lib") //#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") #endif int main(int argc, char** argv) { IrrlichtDevice *device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(720, 455), 16, false, true, false, 0); if (!device) return 1; device->setWindowCaption(L"SpecialFX"); video::IVideoDriver *driver = device->getVideoDriver(); scene::ISceneManager *smgr = device->getSceneManager(); gui::IGUIEnvironment *guiev = device->getGUIEnvironment(); /*********************初始化...******************/ //1.加载一个房间模型 //1.1加载模型网格 scene::IAnimatedMesh* mesh = smgr->getMesh("../media/room.3ds"); //1.2可选:获得网格控制器 //旋转,缩放,颜色设置,透明度设置,反转表面,诸如此类 scene::IMeshManipulator* meshman = smgr->getMeshManipulator(); //在网格上创建平铺的纹理图,优化贴图效果 meshman->makePlanarTextureMapping(mesh->getMesh(0), 0.004f); //1.3 scene::ISceneNode* node = 0;//创建场景界定啊 #if(1) node = smgr->addAnimatedMeshSceneNode(mesh);//将网格加载到场景节点 node->setMaterialTexture(0, driver->getTexture("../media/wall.jpg"));//设置节点纹理 // node->setMaterialFlag(video::EMF_LIGHTING, false);//设置了光照之后需要将材质光照打开 node->getMaterial(0).SpecularColor.set(0, 0, 0, 0);// #endif //2.特效1:水波 //2.1获得一个网格 video::SMaterial material; material.setTexture(0, driver->getTexture("../media/wall.jpg")); mesh = smgr->addHillPlaneMesh( "Hill",//名字,用于获取这个生成的网格:smgr->getMesh() core::dimension2d<f32>(20,20),//titlesize,尺寸 core::dimension2d<u32>(40,40),//titlecount,制定title的数量 &material, // 0,//irr::video::SMaterial 0,//hillheight core::dimension2d<f32>(10,10),//counthills core::dimension2d<f32>(1.0,1.0)//textureRepeatCount,纹理重复次数 ); node = smgr->addAnimatedMeshSceneNode(mesh); // node->setMaterialFlag(video::EMF_LIGHTING, false); node->setPosition(core::vector3df(0, -1, 0)); //2.2创建水面场景节点 node = smgr->addWaterSurfaceSceneNode( mesh->getMesh(0),//irr::IMesh* 3.0f,//waveheight 300,//wavespeed 30.0f//wavelength // 0,//parent // -1,//id // core::vector3df(0, 7, 0),//position // core::vector3df(0, 0, 0),//rotation // core::vector3df(1.0f, 1.0f, 1.0f)//scale ); //2.3设置水波节点 //位置,材质,以及材质属性 node->setPosition(core::vector3df(0, 10, 0)); node->setMaterialTexture(0, driver->getTexture("../media/stones.jpg")); node->setMaterialTexture(1, driver->getTexture("../media/water.jpg")); node->setMaterialType(video::EMT_REFLECTION_2_LAYER); //node->setMaterialFlag(video::EMF_LIGHTING, false);//设置灯光后可以注释掉 //3.布告板 //将布告板绑定到动态移动的光源 //3.1创建一个灯光节点 node = smgr->addLightSceneNode( 0, //parent core::vector3df(0, 0, 0),//position video::SColorf(1.0f, 0.6f, 0.7f, 1.0f),//rgba:0-1 700,//radius -1//id ); //3.2创建一个动画,并绑定到灯光节点 scene::ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator( core::vector3df(0, 150, 0),//center 250,//radius 0.001,//speed core::vector3df(0,1,0),//position方向 0.0,//startPosition 0.0//radiusEllipsoid ); node->addAnimator(anim); anim->drop(); //3.3绑定一个布告板,并初始化布告板的属性:材质,颜色,透明度 node = smgr->addBillboardSceneNode( node,//parent,绑定到灯光节点 core::dimension2d<f32>(50,50)//size ); node->setMaterialFlag(video::EMF_LIGHTING, false);//关闭布告板的光照属性 node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); node->setMaterialTexture(0, driver->getTexture("../media/particlewhite.bmp")); //4.例子系统 //4.1创建粒子系统 scene::IParticleSystemSceneNode* ps = smgr->addParticleSystemSceneNode( false//是否带默认发射器 ); //4.2创建粒子发射器 scene::IParticleEmitter* em = ps->createBoxEmitter( core::aabbox3df(-7, 0, -7, 7, 1, 7),//发射器盒子范围 core::vector3df(0, 0.06, 0),//方向 20,//最小发射速度 100,//最大速度 video::SColor(0, 255, 255, 255),//最深的颜色 video::SColor(0, 255, 255, 255),//最亮的颜色 200,//最短存活时间 2000,//最长存活时间 0,//最大角度 core::dimension2df(10, 10),//最小尺寸 core::dimension2df(20, 20)//最大尺寸 ); //绑定 ps->setEmitter(em); em->drop(); //4.3创建粒子控制器 //此处没有用到 scene::IParticleAffector* paf = ps->createFadeOutParticleAffector(); ps->addAffector(paf); paf->drop(); //4.4设置粒子系统 ps->setPosition(core::vector3df(-70, 60, 40)); ps->setScale(core::vector3df(2, 2, 2)); ps->setMaterialFlag(video::EMF_LIGHTING, false); ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); ps->setMaterialTexture(0, driver->getTexture("../media/fire.bmp")); ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA); //5.创建一个空间灯光节点 scene::IVolumeLightSceneNode* n = smgr->addVolumeLightSceneNode( 0,//parent -1,//id 32,//sub u 32,//sub v video::SColor(0, 255, 255, 255),//foot color video::SColor(0, 0, 0, 0)//tail color ); //设置属性 if (n) { n->setScale(core::vector3df(56, 56, 56)); n->setPosition(core::vector3df(-120, 50, 40)); //n->setMaterialFlag(video::EMF_LIGHTING, false); //创建一个动画,由7张连续图片组成 core::array<video::ITexture*> textures; for (s32 g = 7; g > 0; --g) { core::stringc tmp; tmp = "../media/portal"; tmp += g; tmp += ".bmp"; video::ITexture* t = driver->getTexture(tmp.c_str()); textures.push_back(t); } //创建动画 scene::ISceneNodeAnimator* glow = smgr->createTextureAnimator( textures,// 150,//每帧的时间 true//loop ); n->addAnimator(glow); glow->drop(); } //6.动态阴影 //创建一个动画模型投射出阴影, //6.1创建动画节点 mesh = smgr->getMesh("../media/dwarf.x"); scene::IAnimatedMeshSceneNode* anode = 0; anode = smgr->addAnimatedMeshSceneNode(mesh); anode->setPosition(core::vector3df(-50, 20, -60)); anode->setAnimationSpeed(15); //6.2增加阴影 anode->addShadowVolumeSceneNode(); smgr->setShadowColor(video::SColor(150, 0, 0, 0));//全局的 //6.3设置 //放大模型,随后需要重新单位化法向量 anode->setScale(core::vector3df(2, 2, 2)); anode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); /***********************初始化结束*************/ // smgr->addCameraSceneNode(0, core::vector3df(0, 30, -40), core::vector3df(0, 5, 0)); scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS( ); camera->setPosition(core::vector3df(-50, 50, -150)); device->getCursorControl()->setVisible(false); int lastFPS = -1; while (device->run()) { driver->beginScene(true, true, video::SColor(255, 100, 101, 140)); smgr->drawAll(); guiev->drawAll(); driver->endScene(); int fps = driver->getFPS(); if (lastFPS != fps) { core::stringw str = L"Campfire FX example ["; str += driver->getName(); str += "]FPS.", str += fps; device->setWindowCaption(str.c_str()); lastFPS = fps; } } device->drop(); return 0; }
相关文章推荐
- 向量的倒影 公式推导
- 在irrlicht中播放视频
- irrlicht的显示原理
- Irrlicht引擎在Windows的安装和使用
- Irrlicht引擎在Linux的安装和使用
- Irrlicht学习之载入网格(mesh)文件
- Irrlicht学习之创建GUI界面
- Irrlicht学习之添加中文的支持
- Irrlicht学习之摄像机的探究
- Irrlicht学习之光照的研究
- 使用CopperCube(IrrEdit)创建Irrlicht场景
- Irrlicht学习之载入irr文件和自定义场景节点
- Irrlicht学习之粒子系统的研究
- Irrlicht学习之水波特效的研究
- Irrlicht学习之使用着色器
- 使用VS2010构建CEGUI0.8.3
- 将CEGUI整合进Irrlicht
- Irrlicht 移植到 Android
- 文档翻译之irrlicht1.8-- irr::scene:IMeshLoader
- irrlicht渲染的一帧(可以把irrlicht修改为纯opengl es实现)