登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> 程序员学前班[不再更新,只读] >> 主题: [IrrLicht/中文/例子]IrrLicht 例子的中文讲解 - Tutorial 13: Terrain Rend     [回主站]     [分站链接]
标题
[IrrLicht/中文/例子]IrrLicht 例子的中文讲解 - Tutorial 13: Terrain Rend
clq
浏览(0) + 2009-01-15 15:19:17 发表 编辑

关键字:

[IrrLicht/中文/例子]IrrLicht 例子的中文讲解 - Tutorial 13: Terrain Rend

[在 sdk 1.4.2 中是 12.TerrainRendering]

来自 http://www.cppblog.com/irrwowview/articles/55322.html

这个和 07.Collision [碰撞]例子一样的重要.

--------------------------------------------------
Tutorial 13: Terrain Rendering
本教程简要演示了如何使用IrrLicht引擎的地形(terrain)渲染器。还演示了使用地形三角形选择器根据地形进行碰撞检测。

程序效果如下图所示:



Lets start!

程序的开始并无任何特别。我们包含了需要的头文件和创建一个事件接收器(译注:原文是event listener 事件监听器?看代码就是event receiver嘛,为了统一故译作事件接收器)用于响应用户的按键,如果用户按下‘w’则变成线框模式,而按下‘d’则决定材质在普通贴图和详细贴图之间变换。(译注:在新版本的sdk添加响应‘p’键,则变成只显示顶点)

#include
#include
using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(scene::ISceneNode* terrain)
{
// store pointer to terrain so we can change its drawing mode
Terrain = terrain;
}

bool OnEvent(SEvent event)
{
// check if user presses the key 'W' or 'D'
if (event.EventType == irr::EET_KEY_INPUT_EVENT &&
!event.KeyInput.PressedDown)
{
switch (event.KeyInput.Key)
{
case irr::KEY_KEY_W: // switch wire frame mode
Terrain->setMaterialFlag(video::EMF_WIREFRAME,
!Terrain->getMaterial(0).Wireframe);
return true;
case irr::KEY_KEY_D: // toggle detail map
Terrain->setMaterialType(
Terrain->getMaterial(0).MaterialType
== video::EMT_SOLID ?
video::EMT_DETAIL_MAP : video::EMT_SOLID);
return true;
}
}
return false;
}

private:
scene::ISceneNode* Terrain;
};

就如其它例子那样,使用main函数作为开始。接着询问用户希望使用的渲染器,并启动。

int main()
{
// let user select driver type

video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;

printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");

char i;
std::cin >> i;

switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_SOFTWARE2;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}

// create device
IrrlichtDevice* device = createDevice(driverType,
core::dimension2d(640, 480));

if (device == 0)
return 1; // could not create selected driver.

首先,我们添加标准部件到场景:一个漂亮的IrrLicht引擎标志,一个细小的帮助文本,一个用户可控的摄像机,并取消鼠标光标。

video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* env = device->getGUIEnvironment();

driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);

// add irrlicht logo
env->addImage(driver->getTexture("../../media/irrlichtlogoalpha.tga"),
core::position2d(10,10));



// add some help text
gui::IGUIStaticText* text = env->addStaticText(
L"Press 'W' to change wireframe mode\nPress 'D' to toggle detail map",
core::rect(10,453,200,475), true, true, 0, -1, true);



// add camera
scene::ICameraSceneNode* camera =
smgr->addCameraSceneNodeFPS(0,100.0f,1200.0f);
camera->setPosition(core::vector3df(1900*2,255*2,3700*2));
camera->setTarget(core::vector3df(2397*2,343*2,2700*2));
camera->setFarValue(12000.0f);

// disable mouse cursor
device->getCursorControl()->setVisible(false);

这里来到了地形渲染器场景节点:我们就像添加其它场景节点一样使用ISceneManager::addTerrainSceneNode()方法添加它。只需要一个高度图文件名的参数。高度图是一个简单的灰度纹理。地形渲染器加载这个纹理并根据它创建3D地形。
为了使地形看起来更大,我们使用ISceneManager::setScale()方法设置比例为(40, 4.4, 40)(译注:在新版本的sdk中修改了ISceneManager::addTerrainSceneNode()方法的参数表,可以在这个方法中设置比例而不用setScale()了)。因为在这个场景中没有灯光,所以我们关闭了灯光效果,并设置文件terrain-texture.jpg 作为地形的纹理而文件detailmap3.jpg作为第二层纹理,称为详细贴图。最后,我们设置纹理的比例:第一个纹理只需一次就能覆盖整个地形,而第二个纹理就需要20次。

// add terrain scene node
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
"../../media/terrain-heightmap.bmp");

terrain->setScale(core::vector3df(40, 4.4f, 40));
terrain->setMaterialFlag(video::EMF_LIGHTING, false);

terrain->setMaterialTexture(0, driver->getTexture(
"../../media/terrain-texture.jpg"));
terrain->setMaterialTexture(1, driver->getTexture(
"../../media/detailmap3.jpg"));

terrain->setMaterialType(video::EMT_DETAIL_MAP);
terrain->scaleTexture(1.0f, 20.0f);

为了能与地形进行碰撞,我们创建一个三角形选择器。如果你想了解三角形选择器,可以浏览collision教程。这个三角形选择器根据地形工作的。为了演示它,我们创建一个碰撞响应动作器并附到摄像机上,于是摄像机就不能穿过地形了。

// create triangle selector for the terrain
scene::ITriangleSelector* selector =
smgr->createTerrainTriangleSelector(terrain, 0);
terrain->setTriangleSelector(selector);
selector->drop();

// create collision response animator and attach it to the camera
scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
selector, camera, core::vector3df(60,100,60),
core::vector3df(0,0,0),
core::vector3df(0,50,0));
camera->addAnimator(anim);
anim->drop();

为了使用户能在普通模式和线框模式之间转换,我们根据上面定义的事件接收器类创建一个事件接收器并告诉IrrLicht引擎。另外,我们还添加一个已经在其它例子(译注:mesh viewer)中使用过的天空盒。In addition, we add the skybox which we already used in lots of Irrlicht examples.

// create event receiver
MyEventReceiver receiver(terrain);
device->setEventReceiver(&receiver);

// create skybox
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

smgr->addSkyBoxSceneNode(
driver->getTexture("../../media/irrlicht2_up.jpg"),
driver->getTexture("../../media/irrlicht2_dn.jpg"),
driver->getTexture("../../media/irrlicht2_lf.jpg"),
driver->getTexture("../../media/irrlicht2_rt.jpg"),
driver->getTexture("../../media/irrlicht2_ft.jpg"),
driver->getTexture("../../media/irrlicht2_bk.jpg"));



driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

就是这样,绘制出全部。现在你知道如何在IrrLicht引擎中使用地形了吧。

int lastFPS = -1;

while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0 );

smgr->drawAll();
env->drawAll();

driver->endScene();




// display frames per second in window title



int fps = driver->getFPS();

if (lastFPS != fps)
{
core::stringw str
= L"Terrain Renderer - Irrlicht Engine [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}

device->drop();

return 0;
}





posted on 2008-07-04 11:26 shjy 阅读(9) 评论(0) 编辑 收藏 引用


总数:0 页次:1/0 首页 尾页  
总数:0 页次:1/0 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1