很多朋友喜欢玩游戏,如果不幸有朋友不但喜欢玩游戏,而且还想自己做个游戏,怎么办呢?好办,我们可以用C++来做,下面我们主要介绍一下C++的一款3D图像引擎OGRE,用它我们可以做出至少最简单的windows游戏。下面我们就来看看ogre到底是什么。
简单OGRE框架由两个文件引入:
ExampleApplication.h
ExampleFrameListener.h
这两个文件很重要,他们替我们做了很多底层的工作(其实是导入了很多有用的C++库),让我们来看看其中的 ExampleApplication 类,在这个类中,有几个比较重要的数据成员:
// 指向Root对象的指针
Root *mRoot;
// 指向程序中摄象机的指针
Camera* mCamera;
// 指向场景管理器的指针
SceneManager* mSceneMgr;
// 指向“帧监听器”的指针
FrameListener* mFrameListener;
// 指向渲染窗口的指针
RenderWindow* mWindow;
我们如果要创建3D游戏,需要用到这几个家伙。简单的来说,Root负责所有程序的总调配,而Camera不用说,负责在游戏中充当我们的眼睛,SceneManager用来管理整个游戏场景,FrameListener负责游戏的控制,最后RenderWindow负责将游戏“画”到屏幕上。
OK,我们只要准备这几个家伙,就可以开始工作了。他们可以让我们在屏幕上创建出像CS,魔兽那样的游戏画面。
上面列举了数据成员,让我们再来看一下 ExampleApplication 主要的成员函数:
virtual void go(void)
virtual bool setup(void)
OK,就两个?对!主要的就两个,两个就替我们做了很多事情,让我们看看他们是怎么写的:
其中go函数比较简单,内容如下:
virtual void go(void)
{
if (!setup())
return;
mRoot->startRendering();
}
如果你细心一点的话,会发现,他实际上在其中调用了我们列举的另外一个函数 setup() ,他会负责进行判断,如果setup()函数执行正确,就会调用startRendering()进行渲染,那setup()又做了什么呢?
virtual bool setup(void)
{
mRoot=new Root();
setupResources();
bool carryOn=configure();
if(!carryOn) return false;
chooseSceneManager();
createCamera();
createViewports();
TextureManager::getSingleton().setDefaultNumMipMaps(5);
createScene();
createFrameListener();
return true;
}
可以看出来,实际上setup做了很多重要工作,让我们挨个看看。
首先,他实例化了全局的mRoot,我们之前说过,mRoot和他的名字一样,是老祖宗,他负责调配所有功能。
之后我们执行setupResources(),他负责加载游戏需要用到的资源,例如,纹理,骨骼和网格。
在下面,执行configure(),他就是我们需要对ogre进行的配置,如果配置不成功(例如,用户选择了取消按钮),那么整个程序就退出。
继续往下执行,chooseSceneManager()实际上执行了
mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
他通过mRoot的getSceneManager()函数获得场景管理器并赋值给mSceneMgr,实际上场景管理器是非常重要的,他负责替我们进行场景的渲染,在这里的ST_GENERIC参数代表普通场景类型,其实他有四个选项可供选择,甚至他有一个场景类型枚举定义:
enum SceneType
{
ST_GENERIC; //普通场景
ST_EXTERIOR_CLOSE; //室外封闭场景
ST_EXTERIOR_FAR; //室外无限
ST_INTERIOR; //室内场景
}
如果我们只是做个简单的例子,选择第一项就好了。
接下来程序接着往下走,要执行createCamera()了,因为鉴于我们后面要做的工作,所以首先我们要创建一个摄像机来代表我们的眼睛。
然后程序执行createViewports(),这个函数的作用是创建一个视口,他是做什么的?因为游戏渲染并不是直接在窗口上,而是要在视口中渲染,所以要创建这个东西。
virtual void createViewports(void)
{
Viewport* vp=mWindow->addViewport(mCamera);
vp->setBackgroundColour(ColourValue(0,0,0));
}
有句话说得好,代码能说明一切,看这两行代码,第一行,我们将我们之前创建的摄像机作为参数传递给视口创建函数,好让视口知道我们的眼睛到底在往哪里看,第二行,这个Viewport又绑定到了mWindow这个渲染窗口上来进行渲染。
后面程序执行到了createScene() 函数,他就是需要我们往场景中加入自己元素的函数了,如果你希望将一辆汽车或者飞机放到虚拟的世界里,就可以使用它了,如果你没有设置它,那么除了ogre在前面调用的 chooseSceneManager() 中创建的简单场景之外,一片荒芜。
其实到这里,整个游戏画面部分就已经结束了,画面已经渲染到了屏幕上,接下来我们要干什么呢?当然是让画面动起来,不然我们就只是费劲画了一幅画面而已,这又有什么稀罕的呢?
createFrameListener()就是来帮助我们实现与游戏的交互,我们可以看出他实际上是加入了一个监听器,来监视玩家到底做了什么操作,然后会根据玩家的操作来具体修改每一帧的画面。
然后,让我们再回到go()函数,什么?你已经忘了?呵呵,要知道,我们其实还在go()函数里(其实我们还在如来的手掌心),搞了这么一大通,上面的setup()如果成功,那么最后go()函数的最后一行,就会把我们设定好的程序进行渲染。当然还是由最主要的mRoot来干。
到这里,我相信大家都很疲惫了,让我们喝瓶汽水什么的,歇歇吧。