返回> 网站首页 

Irrlicht 游戏引擎开发 cooliris 界面(二)

yoours2011-01-24 17:03:37 阅读 1159

简介一边听听音乐,一边写写文章。

经过昨天比较枯燥的准备工作后,今天我们的目标是实现本地图片载入 3D 场景,主要内容是熟悉irrlicht引擎,创建一个3D窗口,并绘制图片。

 

总共有两个示例,源代码下载:

example_1.zip

example_2.zip

 

一、irrlicht 简介 

 

irrlicht 游戏引擎的分成五大块:

? Core:              容器类和数学库       namespace irr::core

? Scene:            三维场景绘制和管理      namespace irr::scene

? Video:            图片纹理的载入和管理   namespace irr::video

? GUI:                二维 GUI 控件                 namespace irr::gui

? FileSystem:    文件系统读写                namespace irr::io

 

编写任何一个 irrlicht 程序,首先要获得设备指针 IrrlichtDevice* device:

 

Cpp代码 
  1. video::E_DRIVER_TYPE driver_type = irr::video::EDT_OPENGL;  
  2. core::dimension2d<s32> screen_resolution = core::dimension2d<s32>(1280, 800);  
  3. u32 color_depth = 32;  
  4. bool is_full_screen = true;  
  5.   
  6. IrrlichtDevice* device = irr::createDevice(driver_type, screen_resolution, color_depth,   
  7.     is_full_screen);  

 

driver_type为驱动类型,可以选择OPENGL,DX8 或 DX9。其余几个参数分别为分辨率,颜色深度,是否全屏。

s32, u32 为 irrlicht 定义的类型,分别对应 int 和 unsigned int。

 

获得 device 指针以后,就可以得到属于该 device 的四大块功能:

 

Cpp代码 
  1. video::IVideoDriver* driver = device->getVideoDriver();  
  2. scene::ISceneManager* scene_mgr = device->getSceneManager();  
  3. gui::IGUIEnvironment* gui_env = device->getGUIEnvironment();  
  4. io::IFileSystem* file_system = device->getFileSystem();  

 

通过 driver 载入图片和 texture,通过 scene_mgr 为3d场景添加 irrlicht 内置支持的 mesh 等工作完成后,即可进入主循环,主循环结束时,释放 device,程序结束。其中 beginScene 的参数 SColor(alpha, r, g, b) 为背景色。

 

Cpp代码 
  1. while (device->run())  
  2. {  
  3.     if (device->isWindowActive())  
  4.     {  
  5.         driver->beginScene(truetrue, video::SColor(0, 0, 0, 0));  
  6.         scene_mgr->drawAll();  
  7.         gui_env->drawAll();  
  8.         driver->endScene();  
  9.     }  
  10. }  
  11. device->drop();  

 

值得一提的是 drop() 函数。Irrlicht中大部分类都继承自一个 IReferenceCounted 的接口,类似智能指针。Irrlicht 中的惯例是不使用 delete 删除对象,而调用该接口的 drop() 函数。在添加对象的引用时,调用 grap() 函数。

 

二、创建3D场景
创建3D场景有三个步骤:(1) 通过scene_mgr添加3D物体;(2)为物体贴上纹理;(3) 添加Camera,使物体可见。
在 device->run() 之前添加如下代码
Cpp代码 
  1. // 为场景添加一个立方体,边长100  
  2. scene::ISceneNode* cube = scene_mgr->addCubeSceneNode(100.0f);  
  3.   
  4. // 载入纹理  
  5. video::ITexture* tex = driver->getTexture("box.jpg");  
  6.   
  7. // 将纹理附加到立方体上  
  8. cube->setMaterialTexture(0, tex);  
  9.   
  10. // 将纹理EMF_LIGHTING属性设为false  
  11. // 表示该纹理现实与光源无关,即为图片自身颜色  
  12. cube->setMaterialFlag(video::EMF_LIGHTING, false);  
  13.   
  14. // 使纹理支持半透明,半透明效果与图片相同  
  15. cube->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);  
  16.   
  17. // 添加一个相机,在(700,700,-700)位置,往(0,0,0)位置拍摄。  
  18. scene::ICameraSceneNode* camera = scene_mgr->addCameraSceneNode(0,   
  19.     core::vector3df(700,700,-700), core::vector3df(0,0,0));  
 至此,您应该可以看到一个立方体在场景中央。

以上源代码和所需文件在附件example_1.zip 中。

三、创建 3DWall

源代码参见example_2.zip ,源代码中的内容不再逐行解释了。
Device的驱动为OPENGL,需要修改请转到 util.h 的GetDevice()函数中。
例子二中3D场景的创建,移到了era::wall::CWallManager 的 UpdateScene() 函数中:
Cpp代码 
  1. video::ITexture* tex = era::Util::Instance()->GetDriver()->addTexture("", img);  
  2. core::vector3df size(img->getDimension().Width, img->getDimension().Height, 0.01);  
  3. wallitem = smgr->addCubeSceneNode(1, smgr->getRootSceneNode(), -1,   
  4.     core::vector3df(400*(i/3),300*(1-(i%3)), 0), core::vector3df(0,0,0), size);  
图片被当成 例子一 中 cube 的纹理,填在上面。
你也许会很奇怪,怎么这些 cube 都是扁扁的? 这都是addCubeSceneNode 的最后一个参数 size 的作用。 size将长宽设为图片相同,厚度为0.01. 这样在3D环境中就是个扁扁的图片了。
第四个参数决定了cube在3d场景中的位置core::vector3df(400*(i/3),300*(1-(i%3)), 0)。这样,图片按照如下顺序排列:
1  4  7 ....   
2  5  8  ....
3  6  .......
还值得一提的是,为了节约内存,使用了缩略图。由于irrlicht自身的缩略图算法效率很低,因此程序运行起来,需要等待比较长的时间才能将图片全部载入。另外我在 util.h 编写了 FeatherEdge() 函数,为缩略图添加了阴影(效果并不是很好,但也还过得去了)。
编译运行后,您应该能看到如下画面:

 

 

今天就到这里,下一篇,我们让它动起来 。

微信小程序扫码登陆

文章评论

1159人参与,0条评论