OGRE3D17BeginnersGuide第四章.docx
- 文档编号:29067039
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:35
- 大小:229.87KB
OGRE3D17BeginnersGuide第四章.docx
《OGRE3D17BeginnersGuide第四章.docx》由会员分享,可在线阅读,更多相关《OGRE3D17BeginnersGuide第四章.docx(35页珍藏版)》请在冰豆网上搜索。
OGRE3D17BeginnersGuide第四章
[声明:
本人仅仅英语四级水平,因为喜欢翻译和喜欢Ogre,翻译以下文字,如果哪里有错误或不足还望大虾们见谅,如果您发现有什么错误,请把问题发送到whistleofmysong@,我将尽快的改正。
想到可能对新手有些许帮助,所以对别人是个帮助,对自己也是个鼓励~^_^]
4GettingUserInputandUsingtheFrameListener
【第四章获取用户输入和使用帧监听】
Untilnow,wealwayscreatedsceneswhichwerestaticanddidn'thaveanythingmovinginthem.Wewillchangethiswiththischapter.
【迄今为止,我们总是创建静止的场景并且在场景中没有移动的物体。
在这一章,我们将会改变这种现状。
】
Inthischapter,wewill:
*LearnwhataFrameListeneris
*Learnhowtoprocessuserinput
*Combinebothconceptstocreateourowncameracontrol
Solet'sgetonwithit...
【
在这章,我们将会:
●认识什么是帧监听
●认识如何处理用户输入
●结合两种概念创建我们自己的相机控制
】
Preparingascene
【准备一个场景】
Beforeaddingmovingthingstoourscene,weneedascenetoaddthemto.Solet'screateascene.
【在添加移动物体之前,我们首先应创建一个可添加物体的场景。
然后让我们一起创建一个场景吧。
】
Timeforaction–preparingascene
【实践时刻——准备一个场景】
Wewilluseaslightlydifferentversionofthescenefromthepreviouschapter:
【我们将使用和之前章节中略微不同的创建场景的版本。
】
1.DeleteallcodeinthecreateScene()andthecreateCamera()functions.
【1.删除createScene()和createCamera()函数中的所有代码:
】
2.DeletethecreateViewports()function.
【2.删除createViewports()函数。
】
3.Addanewmembervariabletotheclass.Thismembervariableisapointertoa
scenenode:
【3.添加一个新的成员变量到类中。
这个成员变量是一个场景结点的指针:
】
private:
Ogre:
:
SceneNode*_SinbadNode;
4.CreateaplaneandaddittothesceneusingthecreateScene()method:
【4.使用createScene()函数创建一个平面并添加它到场景之中:
】
Ogre:
:
Planeplane(Vector3:
:
UNIT_Y,-10);
Ogre:
:
MeshManager:
:
getSingleton().createPlane("plane",ResourceGroupManager:
:
DEFAULT_RESOURCE_GROUP_NAME,plane,1500,1500,200,200,true,1,5,5,Vector3:
:
UNIT_Z);
Ogre:
:
Entity*ent=mSceneMgr->createEntity("LightPlaneEntity","plane");
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
ent->setMaterialName("Examples/BeachStones");
5.Thenaddalighttothescene:
【5.然后添加一个光源到场景中:
】
Ogre:
:
Light*light=mSceneMgr->createLight("Light1");
light->setType(Ogre:
:
Light:
:
LT_DIRECTIONAL);
light->setDirection(Ogre:
:
Vector3(1,-1,0));
6.WealsoneedaninstanceofSinbad;createanodeandattachtheinstancetoit:
【6.我们也需要一个Sinbad的实例,创建一个结点并关联实例。
】
Ogre:
:
SceneNode*node=mSceneMgr->createSceneNode("Node1");
mSceneMgr->getRootSceneNode()->addChild(node);
Ogre:
:
Entity*Sinbad=mSceneMgr->createEntity("Sinbad","Sinbad.mesh");
_SinbadNode=node->createChildSceneNode("SinbadNode");
_SinbadNode->setScale(3.0f,3.0f,3.0f);
_SinbadNode->setPosition(Ogre:
:
Vector3(0.0f,4.0f,0.0f));
_SinbadNode->attachObject(Sinbad);
7.Wealsowantshadowsinthisscene;soactivatethem:
【7.我们也想在场景中增加阴影;所以添加它们:
】
mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
8.Createacameraandpositionitat(0,100,200)andletitlookat(0,0,0);remembertoaddthecodetothecreateCamera()function:
【8.创建一个摄像机并放置它在(0,100,200)并把镜头朝向(0,0,0);记住添加代码到createCamera()函数中。
】
mCamera=mSceneMgr->createCamera("MyCamera1");
mCamera->setPosition(0,100,200);
mCamera->lookAt(0,0,0);
mCamera->setNearClipDistance(5);
9.Compileandruntheapplication,andyoushouldseethefollowingimage:
【编译运行,你将会看到下面图中的效果】
Whatjusthappened?
【刚刚发生了什么?
】
Weusedtheknowledgefromthepreviouschapterstocreateascene.Weshouldbeable
tounderstandwhathappened.Ifnot,weshouldgobacktothepreviouschaptersandread
themagainuntilweunderstandeverything.
【我们使用在之前章节学到的东西创建了一个场景。
我们应可以理解发生了什么。
如果没有的话,我们就应该回过头再看看之前的章节直到我们可以理解为止。
】
Addingmovementtothescene
【添加运动到场景之中】
Wehavecreatedourscene;nowlet'saddmovementtothescene.
【我们已经创建了场景;现在让我们把运动添加进场景中。
】
Timeforaction–addingmovementtothescene
【实践时刻——添加运动到场景中】
Upuntilnow,weonlyhadoneclass,namely,ExampleApplication.Thistimeweneed
anotherone:
【目前为止,我们只有一个类,即是,ExampleApplication。
这次我们需要另一个类:
】
1.Createanewclass,nameitExample25FrameListener,andletitinheritpublicly
fromOgre:
:
FrameListener:
【1.创建一个新类,命名为Example25FrameListener,并使它从Ogre:
:
FrameListener中公有继承。
】
classExample25FrameListener:
publicOgre:
:
FrameListener
{
};
2.Addaprivatemembervariable,whichisanOgre:
:
SceneNodepointer,andname
it_node:
【2.添加一个私有的成员变量,一个Ogre:
:
SceneNode的指针,并把它命名为_node】
private:
Ogre:
:
SceneNode*_node;
3.AddapublicconstructorthattakesanOgre:
:
SceneNodepointerasaparameter
andassignsittothemembernodepointer:
【3.添加接收一个Ogre:
:
SceneNode指针为参数的公有构造函数,并把这个指针赋值操作给成员变量node指针。
】
public:
Example25FrameListener(Ogre:
:
SceneNode*node)
{
_node=node;
}
4.AddanewfunctioncalledframeStarted(FrameEvent&evt),whichtranslates
themembernodewith(0,0,0.1)andthenreturnstrue:
【4.添加一个新的frameStarted(FrameEvent&evt)函数,在函数中用(0,0,0.1)变换成员node,然后返回true:
】
boolframeStarted(constOgre:
:
FrameEvent&evt)
{
_node->translate(Ogre:
:
Vector3(0.1,0,0));
returntrue;
}
5.AddanewmembervariabletoholdthepointertotheFrameListener,whichwe
willcreatelater:
【5.添加一个FrameListener指针为成员变量。
】
Ogre:
:
FrameListener*FrameListener;
6.AddaconstructorwhichinitsthepointerwithNULLandadestructorwhichdestroys
theFrameListenerwhentheapplicationisclosed:
【6.添加一个初始化FrameListener为NULL的构造函数和一个当程序结束时删除FrameListener的析构函数。
】
Example25()
{
FrameListener=NULL;
}
~Example25()
{
if(FrameListener)
{
deleteFrameListener;
}
}
7.NowcreateanewfunctioninExampleApplicationcalledcreateFrameListener.Inthisfunction,createaninstanceoftheFrameListenerwedefinedandadditusingmRoot:
【现在,在ExampleApplication类中创建一个名为createFrameListener的新函数。
在这个函数中,创建一个FrameListener的实例并添加它到mRoot:
】
voidcreateFrameListener()
{
FrameListener=newExample25FrameListener(_SinbadNode);
mRoot->addFrameListener(FrameListener);
}
8.Compileandruntheapplication.Youshouldseethesamesceneasseenearlier,
butthistime,theinstanceofSinbadmovesrightandyoucan'tmovethecameraor
closetheapplicationwiththeEscapekey.Toclosetheapplication,clicktheXbutton
ontheconsolewindows,orifyoustartedtheapplicationfromaconsole,youcan
useCTRL+C.
【8.编译运行程序。
你应看到和之前相同的场景。
但是这次,Sinbad的实例向右边移动了并且你不能移动摄像机或用Escape键关闭程序。
你可以使用控制台窗口的X按钮关闭窗口。
如果你从控制台启动程序,你可以使用CTRL+C来结束程序。
】
Whatjusthappened?
【刚刚发生了什么?
】
Weaddedanewclasstoourcodewhichmovesourscenenode.
【我们添加了一个可以移动我们场景结点的类到我们的代码中。
】
FrameListener
【帧监听】
ThenewconceptwehaveencounteredhereistheconceptofFrameListeners.Asthenamesuggests,aFrameListenerisbasedontheobserverpattern.WecanaddaclassinstancewhichinheritsfromtheOgre:
:
FrameListenerinterfacetoourOgre3DrootinstanceusingtheaddFrameListener()methodofOgre:
:
Root.Whenthisclassinstanceisadded,ourclassgetsnotifiedwhencertaineventshappen.Inthisexample,weoverrodetheframeStarted()method.
【我们在此遇到的一个新概念就是帧监听。
顾名思义,帧监听是基于一个观察者的模式。
我们可以添加一个类的实例。
你可以使用Ogre:
:
Root的addFrameListener()方法,通过继承自Ogre:
:
FrameListener的接口,添加一个对象到我们的Ogre3D根对象中。
当对象被添加时,在确定的事件发生时我们的类就会得到通知。
在这个例子中,我们重写了frameStarted()方法。
】
Beforeaframe(byframe,wemeanasinglepictureofthescene)isrendered,Ogre:
:
RootiteratesoveralladdedFrameListenersandcallstheframeStarted()methodofeachone.Inourimplementation(seestep4)ofthisfunction,wetranslatedthenode0.1unitsonthex-axis.ThisnodewaspassedtotheFramelistenerinitsconstructor.Therefore,eachtimethesceneisrendered,thenodeistranslatedabit,andasaresult,themodelmoves.Aswehaveseenduringtherunningoftheapplication,wecan'tmoveourcameraorexitourapplicationusingtheEscapekey.ThisisbecausethesethingsweredonebytheFrameListener,whichcomeswiththeExampleApplicationframework.TheExampleApplicationframeworkcomeswiththeSDK.Nowthatwehavereplaceditwithourownimplementation,wecan'tusethefunctionstheFrameListeneroffersanylonger.
Butwewillreimplementmostoftheminthischapter,sonoworries.Ifneeded,wecouldstill
callthefunctionsofthebaseclasstogetourdefaultbehaviorback.Instep4,ourfunctionreturnstrue.Ifitreturnedfalse,Ogre3Dwouldinterpretthisasasignaltodropoutoftherenderloop,andwiththis,theapplicationwouldbeclosed.Wewillusethisfacttoreimplementthe"pressEscapetoexittheapplication"function.
【在帧(帧,意思是指场景中的单个图像)被渲染之前,Ogre:
:
Root遍历所有添加的Framelistener并调用每个的frameStarted()方法。
我们第四步中的函数定义中,我们沿X轴每帧0.1单位的速率变换结点。
这个结点通过Example25FrameListener构造函数的返回地址传递给Framelistener。
因此,场景每次被渲染的时候,结点就变换一点位置。
结果,模型就移动了。
正如我们在程序运行时看到的,我们不能移动摄像机或使用Escape键退出。
这是因为这些是由Framelistener来操作的,而这个FrameListener是ExampleApplication框架自带的。
ExampleApplication是SDK自带的。
现在我们代替其原有的FrameListener,使用我们自己定义的实现过程。
这样我们就不能使用自带的Framelistener,但是这章我们将会重新实现他们中的大部分,所以不用担心。
如果需要,我们可能仍然调用基类的成员函数来获得默认的行为。
在第四步中,我们函数返回true。
如果返回false,Ogre3D将会解释false为退出渲染循环的标志,而与此同时,程序就会结束。
我们将会使用重新实现“按Escape键退出”的函数。
】
Popquiz–designpatternofFrameListener
【简单测试——FrameListener的设计模式】
1.OnwhichdesignpatternistheFrameListenerconceptbased?
【1.Framelistener概念的模式是基于?
】
a.Decorator【装饰者】
b.Bridge【桥】
c.Observer【观察者】
Modifyingthecodetobetimebasedratherthanframebased
【修改代码使其代替基于每帧的运动为基于时间的运动】
Dependingonyourcomputer,themodelinthescenemightbemovingquitefastorquite
sloworjustattherightspeed.Thereasonforthedifferentspeedsatwhichthemodelmight
moveisthat,inourcode,wemovethemodel0.1unitsonthez-axisbeforeanewframeis
renderedeverytime.Anewcomputermightbeabletorenderthescenewith100frames
persecond;thiswouldmovethemodel10unitspersecond.Whenusinganoldcomputer,
wecouldhave30framesperseconds,thenthemodelwouldonlymove3units.Thisisonlyonethird,ascomparedtothenewcomputers.Normally,wewantourapplicationtobeconsistentacrossdifferentplatformsandcapabilitiessothatitwillr
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OGRE3D17BeginnersGuide 第四