这一章练习一下光源的使用,光源分为三种:点光源,聚光源,有向光。具体内容前面说过,这里就不解释了。
继续在上一章的程序的基础上实现。
1、创建摄像机(Camera)
createCamera()函数是继承自ExampleApplication的虚函数,把它实现了。
1 class Example1:public ExampleApplication 2 { 3 public: 4 //..........其他代码 5 virtual void createCamera() 6 { 7 mCamera = mSceneMgr->createCamera("PlayerCam");//创建摄像机 8 mCamera->setPosition(Vector3(0,10,500));//位置 9 mCamera->lookAt(Vector3(0,0,0));//方向 10 mCamera->setNearClipDistance(5);//近截面 11 } 12 //....其他代码 13 }
2、创建视口(Viewport)
1 virtual void createViewports() 2 { 3 Viewport* vp = mWindow->addViewport(mCamera);//将视口添加到摄像机 4 vp->setBackgroundColour(ColourValue(0,0,0)); 5 mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));//设置纵宽比 6 }
总结:摄像机与视口的区别与联系
1、摄像机相当于现实世界中人的位置,视口相当于人的眼睛,就好象你要看电影一样,首先你要选好座位(摄像机),然后你才能看电影(视口)。所以必须在创建过摄像机口创建视口,并绑定到摄像机上。
2、一个视口只能绑定到一个摄像机上,这个很好理解。一个人只有一双眼睛,也只能占一个位置。
3、一个摄像机可以绑定多个视口。相当于一个电影可有多人观看。
4、一个场景可以绑定那个多个摄像机。
3、设置光源
1 void createScene() 2 { 3 Entity *ent; 4 Light *light; 5 mSceneMgr->setAmbientLight( ColourValue( 0, 0, 0 ) );//设置环境光全黑 6 mSceneMgr->setShadowTechnique( SHADOWTYPE_STENCIL_ADDITIVE );//阴影类型 7 ent = mSceneMgr->createEntity("robot", "robot.mesh"); 8 ent->setCastShadows(true);//作为投射阴影体 9 mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); 10 11 Plane plane(Vector3::UNIT_Y, 0);//创建一个平面,法线为Y轴,与原点距离为0 12 MeshManager::getSingleton().createPlane("ground", //面板名称为“ground” 13 ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 14 1500,1500,//平面尺寸 15 20,20,true,1,5,5,Vector3::UNIT_Z); 16 ent = mSceneMgr->createEntity("GroundEntity", "ground");//创建实体面板 17 mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);//将面板添加到场景管理器 18 ent->setMaterialName("Examples/Rockwall");//给面板添加材质 19 ent->setCastShadows(false);//本身不作为投射阴影体 20 //点光源 21 light = mSceneMgr->createLight("Light1"); 22 light->setType(Light::LT_POINT); 23 light->setPosition(Vector3(0, 150, 250)); 24 light->setDiffuseColour(1.0, 0.0, 0.0);//漫射色 25 light->setSpecularColour(1.0, 0.0, 0.0);//镜面色 26 //有向光 27 light = mSceneMgr->createLight("Light3"); 28 light->setType(Light::LT_DIRECTIONAL); 29 light->setDiffuseColour(ColourValue(.25, .25, 0));//漫射色 30 light->setSpecularColour(ColourValue(.25, .25, 0));//镜面色 31 light->setDirection(Vector3( 0, -1, 1 ));//方向,把这个理解为空间向量最好,指向为远点 32 //聚光源 33 light = mSceneMgr->createLight("Light2"); 34 light->setType(Light::LT_SPOTLIGHT); 35 light->setDiffuseColour(0, 0, 1.0);//漫射色 36 light->setSpecularColour(0, 0, 1.0);//镜面色 37 light->setDirection(-1, -1, 0);//方向,指向为远点 38 light->setPosition(Vector3(300, 300, 0));//位置 39 light->setSpotlightRange(Degree(35), Degree(50));//光线宽度 40 }
效果如图:
代码解释
平面的设置,看源代码:
1 Plane (const Vector3& rkNormal, Real fConstant);//构造函数如此而已,以法向量为基础创建一平面,Normal的意思是就法向量啊,你记得这个单词吗?
看代码,关键是在UNIT_Y上,这是一个静态常成员变量, 如 static const Vector2 UNIT_Y;
1 Plane plane(Vector3::UNIT_Y, 0);//Y轴作为平面的法线,第二个参数表示平面离原点距离
是否接受投射的阴影
1 virtual void setCastShadows(bool castShadows);//
为true时,本身接收投射阴影,否则不接收。
光源设置
其中的LightTypes为light成员变量,代表三种光源类型
1 enum LightTypes 2 { 3 /// Point light sources give off light equally in all directions, so require only position not direction 4 LT_POINT = 0,//点光源 5 /// Directional lights simulate parallel light beams from a distant source, hence have direction but no position 6 LT_DIRECTIONAL = 1,//有向光 7 /// Spotlights simulate a cone of light from a source so require position and direction, plus extra values for falloff 8 LT_SPOTLIGHT = 2//聚光源 9 };
漫色光与镜面光
1 void setSpecularColour(Real red, Real green, Real blue);//镜面色 2 void setDiffuseColour(Real red, Real green, Real blue);//漫射光
参数的取值范围是从0到1的浮点数,全0为黑色,全1为白色。至于他们的具体定义与效果则需要3D图形学方面的知识了。