aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp')
-rw-r--r--libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp570
1 files changed, 285 insertions, 285 deletions
diff --git a/libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp b/libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp
index d829244..6603e12 100644
--- a/libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp
+++ b/libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp
@@ -1,285 +1,285 @@
1/** Example 012 Terrain Rendering 1/** Example 012 Terrain Rendering
2 2
3This tutorial will briefly show how to use the terrain renderer of Irrlicht. It 3This tutorial will briefly show how to use the terrain renderer of Irrlicht. It
4will also show the terrain renderer triangle selector to be able to do 4will also show the terrain renderer triangle selector to be able to do
5collision detection with terrain. 5collision detection with terrain.
6 6
7Note that the Terrain Renderer in Irrlicht is based on Spintz' 7Note that the Terrain Renderer in Irrlicht is based on Spintz'
8GeoMipMapSceneNode, lots of thanks go to him. DeusXL provided a new elegant 8GeoMipMapSceneNode, lots of thanks go to him. DeusXL provided a new elegant
9simple solution for building larger area on small heightmaps -> terrain 9simple solution for building larger area on small heightmaps -> terrain
10smoothing. 10smoothing.
11 11
12In the beginning there is nothing special. We include the needed header files 12In the beginning there is nothing special. We include the needed header files
13and create an event listener to listen if the user presses a key: The 'W' key 13and create an event listener to listen if the user presses a key: The 'W' key
14switches to wireframe mode, the 'P' key to pointcloud mode, and the 'D' key 14switches to wireframe mode, the 'P' key to pointcloud mode, and the 'D' key
15toggles between solid and detail mapped material. 15toggles between solid and detail mapped material.
16*/ 16*/
17#include <irrlicht.h> 17#include <irrlicht.h>
18#include "driverChoice.h" 18#include "driverChoice.h"
19 19
20using namespace irr; 20using namespace irr;
21 21
22#ifdef _MSC_VER 22#ifdef _MSC_VER
23#pragma comment(lib, "Irrlicht.lib") 23#pragma comment(lib, "Irrlicht.lib")
24#endif 24#endif
25 25
26 26
27class MyEventReceiver : public IEventReceiver 27class MyEventReceiver : public IEventReceiver
28{ 28{
29public: 29public:
30 30
31 MyEventReceiver(scene::ISceneNode* terrain, scene::ISceneNode* skybox, scene::ISceneNode* skydome) : 31 MyEventReceiver(scene::ISceneNode* terrain, scene::ISceneNode* skybox, scene::ISceneNode* skydome) :
32 Terrain(terrain), Skybox(skybox), Skydome(skydome), showBox(true), showDebug(false) 32 Terrain(terrain), Skybox(skybox), Skydome(skydome), showBox(true), showDebug(false)
33 { 33 {
34 Skybox->setVisible(showBox); 34 Skybox->setVisible(showBox);
35 Skydome->setVisible(!showBox); 35 Skydome->setVisible(!showBox);
36 } 36 }
37 37
38 bool OnEvent(const SEvent& event) 38 bool OnEvent(const SEvent& event)
39 { 39 {
40 // check if user presses the key 'W' or 'D' 40 // check if user presses the key 'W' or 'D'
41 if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown) 41 if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
42 { 42 {
43 switch (event.KeyInput.Key) 43 switch (event.KeyInput.Key)
44 { 44 {
45 case irr::KEY_KEY_W: // switch wire frame mode 45 case irr::KEY_KEY_W: // switch wire frame mode
46 Terrain->setMaterialFlag(video::EMF_WIREFRAME, 46 Terrain->setMaterialFlag(video::EMF_WIREFRAME,
47 !Terrain->getMaterial(0).Wireframe); 47 !Terrain->getMaterial(0).Wireframe);
48 Terrain->setMaterialFlag(video::EMF_POINTCLOUD, false); 48 Terrain->setMaterialFlag(video::EMF_POINTCLOUD, false);
49 return true; 49 return true;
50 case irr::KEY_KEY_P: // switch wire frame mode 50 case irr::KEY_KEY_P: // switch wire frame mode
51 Terrain->setMaterialFlag(video::EMF_POINTCLOUD, 51 Terrain->setMaterialFlag(video::EMF_POINTCLOUD,
52 !Terrain->getMaterial(0).PointCloud); 52 !Terrain->getMaterial(0).PointCloud);
53 Terrain->setMaterialFlag(video::EMF_WIREFRAME, false); 53 Terrain->setMaterialFlag(video::EMF_WIREFRAME, false);
54 return true; 54 return true;
55 case irr::KEY_KEY_D: // toggle detail map 55 case irr::KEY_KEY_D: // toggle detail map
56 Terrain->setMaterialType( 56 Terrain->setMaterialType(
57 Terrain->getMaterial(0).MaterialType == video::EMT_SOLID ? 57 Terrain->getMaterial(0).MaterialType == video::EMT_SOLID ?
58 video::EMT_DETAIL_MAP : video::EMT_SOLID); 58 video::EMT_DETAIL_MAP : video::EMT_SOLID);
59 return true; 59 return true;
60 case irr::KEY_KEY_S: // toggle skies 60 case irr::KEY_KEY_S: // toggle skies
61 showBox=!showBox; 61 showBox=!showBox;
62 Skybox->setVisible(showBox); 62 Skybox->setVisible(showBox);
63 Skydome->setVisible(!showBox); 63 Skydome->setVisible(!showBox);
64 return true; 64 return true;
65 case irr::KEY_KEY_X: // toggle debug information 65 case irr::KEY_KEY_X: // toggle debug information
66 showDebug=!showDebug; 66 showDebug=!showDebug;
67 Terrain->setDebugDataVisible(showDebug?scene::EDS_BBOX_ALL:scene::EDS_OFF); 67 Terrain->setDebugDataVisible(showDebug?scene::EDS_BBOX_ALL:scene::EDS_OFF);
68 return true; 68 return true;
69 default: 69 default:
70 break; 70 break;
71 } 71 }
72 } 72 }
73 73
74 return false; 74 return false;
75 } 75 }
76 76
77private: 77private:
78 scene::ISceneNode* Terrain; 78 scene::ISceneNode* Terrain;
79 scene::ISceneNode* Skybox; 79 scene::ISceneNode* Skybox;
80 scene::ISceneNode* Skydome; 80 scene::ISceneNode* Skydome;
81 bool showBox; 81 bool showBox;
82 bool showDebug; 82 bool showDebug;
83}; 83};
84 84
85 85
86/* 86/*
87The start of the main function starts like in most other example. We ask the 87The start of the main function starts like in most other example. We ask the
88user for the desired renderer and start it up. This time with the advanced 88user for the desired renderer and start it up. This time with the advanced
89parameter handling. 89parameter handling.
90*/ 90*/
91int main() 91int main()
92{ 92{
93 // ask user for driver 93 // ask user for driver
94 video::E_DRIVER_TYPE driverType=driverChoiceConsole(); 94 video::E_DRIVER_TYPE driverType=driverChoiceConsole();
95 if (driverType==video::EDT_COUNT) 95 if (driverType==video::EDT_COUNT)
96 return 1; 96 return 1;
97 97
98 // create device with full flexibility over creation parameters 98 // create device with full flexibility over creation parameters
99 // you can add more parameters if desired, check irr::SIrrlichtCreationParameters 99 // you can add more parameters if desired, check irr::SIrrlichtCreationParameters
100 irr::SIrrlichtCreationParameters params; 100 irr::SIrrlichtCreationParameters params;
101 params.DriverType=driverType; 101 params.DriverType=driverType;
102 params.WindowSize=core::dimension2d<u32>(640, 480); 102 params.WindowSize=core::dimension2d<u32>(640, 480);
103 IrrlichtDevice* device = createDeviceEx(params); 103 IrrlichtDevice* device = createDeviceEx(params);
104 104
105 if (device == 0) 105 if (device == 0)
106 return 1; // could not create selected driver. 106 return 1; // could not create selected driver.
107 107
108 108
109 /* 109 /*
110 First, we add standard stuff to the scene: A nice irrlicht engine 110 First, we add standard stuff to the scene: A nice irrlicht engine
111 logo, a small help text, a user controlled camera, and we disable 111 logo, a small help text, a user controlled camera, and we disable
112 the mouse cursor. 112 the mouse cursor.
113 */ 113 */
114 114
115 video::IVideoDriver* driver = device->getVideoDriver(); 115 video::IVideoDriver* driver = device->getVideoDriver();
116 scene::ISceneManager* smgr = device->getSceneManager(); 116 scene::ISceneManager* smgr = device->getSceneManager();
117 gui::IGUIEnvironment* env = device->getGUIEnvironment(); 117 gui::IGUIEnvironment* env = device->getGUIEnvironment();
118 118
119 driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true); 119 driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
120 120
121 // add irrlicht logo 121 // add irrlicht logo
122 env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"), 122 env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
123 core::position2d<s32>(10,10)); 123 core::position2d<s32>(10,10));
124 124
125 //set other font 125 //set other font
126 env->getSkin()->setFont(env->getFont("../../media/fontlucida.png")); 126 env->getSkin()->setFont(env->getFont("../../media/fontlucida.png"));
127 127
128 // add some help text 128 // add some help text
129 env->addStaticText( 129 env->addStaticText(
130 L"Press 'W' to change wireframe mode\nPress 'D' to toggle detail map\nPress 'S' to toggle skybox/skydome", 130 L"Press 'W' to change wireframe mode\nPress 'D' to toggle detail map\nPress 'S' to toggle skybox/skydome",
131 core::rect<s32>(10,421,250,475), true, true, 0, -1, true); 131 core::rect<s32>(10,421,250,475), true, true, 0, -1, true);
132 132
133 // add camera 133 // add camera
134 scene::ICameraSceneNode* camera = 134 scene::ICameraSceneNode* camera =
135 smgr->addCameraSceneNodeFPS(0,100.0f,1.2f); 135 smgr->addCameraSceneNodeFPS(0,100.0f,1.2f);
136 136
137 camera->setPosition(core::vector3df(2700*2,255*2,2600*2)); 137 camera->setPosition(core::vector3df(2700*2,255*2,2600*2));
138 camera->setTarget(core::vector3df(2397*2,343*2,2700*2)); 138 camera->setTarget(core::vector3df(2397*2,343*2,2700*2));
139 camera->setFarValue(42000.0f); 139 camera->setFarValue(42000.0f);
140 140
141 // disable mouse cursor 141 // disable mouse cursor
142 device->getCursorControl()->setVisible(false); 142 device->getCursorControl()->setVisible(false);
143 143
144 /* 144 /*
145 Here comes the terrain renderer scene node: We add it just like any 145 Here comes the terrain renderer scene node: We add it just like any
146 other scene node to the scene using 146 other scene node to the scene using
147 ISceneManager::addTerrainSceneNode(). The only parameter we use is a 147 ISceneManager::addTerrainSceneNode(). The only parameter we use is a
148 file name to the heightmap we use. A heightmap is simply a gray scale 148 file name to the heightmap we use. A heightmap is simply a gray scale
149 texture. The terrain renderer loads it and creates the 3D terrain from 149 texture. The terrain renderer loads it and creates the 3D terrain from
150 it. 150 it.
151 151
152 To make the terrain look more big, we change the scale factor of 152 To make the terrain look more big, we change the scale factor of
153 it to (40, 4.4, 40). Because we don't have any dynamic lights in the 153 it to (40, 4.4, 40). Because we don't have any dynamic lights in the
154 scene, we switch off the lighting, and we set the file 154 scene, we switch off the lighting, and we set the file
155 terrain-texture.jpg as texture for the terrain and detailmap3.jpg as 155 terrain-texture.jpg as texture for the terrain and detailmap3.jpg as
156 second texture, called detail map. At last, we set the scale values for 156 second texture, called detail map. At last, we set the scale values for
157 the texture: The first texture will be repeated only one time over the 157 the texture: The first texture will be repeated only one time over the
158 whole terrain, and the second one (detail map) 20 times. 158 whole terrain, and the second one (detail map) 20 times.
159 */ 159 */
160 160
161 // add terrain scene node 161 // add terrain scene node
162 scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode( 162 scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
163 "../../media/terrain-heightmap.bmp", 163 "../../media/terrain-heightmap.bmp",
164 0, // parent node 164 0, // parent node
165 -1, // node id 165 -1, // node id
166 core::vector3df(0.f, 0.f, 0.f), // position 166 core::vector3df(0.f, 0.f, 0.f), // position
167 core::vector3df(0.f, 0.f, 0.f), // rotation 167 core::vector3df(0.f, 0.f, 0.f), // rotation
168 core::vector3df(40.f, 4.4f, 40.f), // scale 168 core::vector3df(40.f, 4.4f, 40.f), // scale
169 video::SColor ( 255, 255, 255, 255 ), // vertexColor 169 video::SColor ( 255, 255, 255, 255 ), // vertexColor
170 5, // maxLOD 170 5, // maxLOD
171 scene::ETPS_17, // patchSize 171 scene::ETPS_17, // patchSize
172 4 // smoothFactor 172 4 // smoothFactor
173 ); 173 );
174 174
175 terrain->setMaterialFlag(video::EMF_LIGHTING, false); 175 terrain->setMaterialFlag(video::EMF_LIGHTING, false);
176 176
177 terrain->setMaterialTexture(0, 177 terrain->setMaterialTexture(0,
178 driver->getTexture("../../media/terrain-texture.jpg")); 178 driver->getTexture("../../media/terrain-texture.jpg"));
179 terrain->setMaterialTexture(1, 179 terrain->setMaterialTexture(1,
180 driver->getTexture("../../media/detailmap3.jpg")); 180 driver->getTexture("../../media/detailmap3.jpg"));
181 181
182 terrain->setMaterialType(video::EMT_DETAIL_MAP); 182 terrain->setMaterialType(video::EMT_DETAIL_MAP);
183 183
184 terrain->scaleTexture(1.0f, 20.0f); 184 terrain->scaleTexture(1.0f, 20.0f);
185 185
186 /* 186 /*
187 To be able to do collision with the terrain, we create a triangle selector. 187 To be able to do collision with the terrain, we create a triangle selector.
188 If you want to know what triangle selectors do, just take a look into the 188 If you want to know what triangle selectors do, just take a look into the
189 collision tutorial. The terrain triangle selector works together with the 189 collision tutorial. The terrain triangle selector works together with the
190 terrain. To demonstrate this, we create a collision response animator 190 terrain. To demonstrate this, we create a collision response animator
191 and attach it to the camera, so that the camera will not be able to fly 191 and attach it to the camera, so that the camera will not be able to fly
192 through the terrain. 192 through the terrain.
193 */ 193 */
194 194
195 // create triangle selector for the terrain 195 // create triangle selector for the terrain
196 scene::ITriangleSelector* selector 196 scene::ITriangleSelector* selector
197 = smgr->createTerrainTriangleSelector(terrain, 0); 197 = smgr->createTerrainTriangleSelector(terrain, 0);
198 terrain->setTriangleSelector(selector); 198 terrain->setTriangleSelector(selector);
199 199
200 // create collision response animator and attach it to the camera 200 // create collision response animator and attach it to the camera
201 scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator( 201 scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
202 selector, camera, core::vector3df(60,100,60), 202 selector, camera, core::vector3df(60,100,60),
203 core::vector3df(0,0,0), 203 core::vector3df(0,0,0),
204 core::vector3df(0,50,0)); 204 core::vector3df(0,50,0));
205 selector->drop(); 205 selector->drop();
206 camera->addAnimator(anim); 206 camera->addAnimator(anim);
207 anim->drop(); 207 anim->drop();
208 208
209 /* If you need access to the terrain data you can also do this directly via the following code fragment. 209 /* If you need access to the terrain data you can also do this directly via the following code fragment.
210 */ 210 */
211 scene::CDynamicMeshBuffer* buffer = new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_16BIT); 211 scene::CDynamicMeshBuffer* buffer = new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_16BIT);
212 terrain->getMeshBufferForLOD(*buffer, 0); 212 terrain->getMeshBufferForLOD(*buffer, 0);
213 video::S3DVertex2TCoords* data = (video::S3DVertex2TCoords*)buffer->getVertexBuffer().getData(); 213 video::S3DVertex2TCoords* data = (video::S3DVertex2TCoords*)buffer->getVertexBuffer().getData();
214 // Work on data or get the IndexBuffer with a similar call. 214 // Work on data or get the IndexBuffer with a similar call.
215 buffer->drop(); // When done drop the buffer again. 215 buffer->drop(); // When done drop the buffer again.
216 216
217 /* 217 /*
218 To make the user be able to switch between normal and wireframe mode, 218 To make the user be able to switch between normal and wireframe mode,
219 we create an instance of the event receiver from above and let Irrlicht 219 we create an instance of the event receiver from above and let Irrlicht
220 know about it. In addition, we add the skybox which we already used in 220 know about it. In addition, we add the skybox which we already used in
221 lots of Irrlicht examples and a skydome, which is shown mutually 221 lots of Irrlicht examples and a skydome, which is shown mutually
222 exclusive with the skybox by pressing 'S'. 222 exclusive with the skybox by pressing 'S'.
223 */ 223 */
224 224
225 // create skybox and skydome 225 // create skybox and skydome
226 driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); 226 driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
227 227
228 scene::ISceneNode* skybox=smgr->addSkyBoxSceneNode( 228 scene::ISceneNode* skybox=smgr->addSkyBoxSceneNode(
229 driver->getTexture("../../media/irrlicht2_up.jpg"), 229 driver->getTexture("../../media/irrlicht2_up.jpg"),
230 driver->getTexture("../../media/irrlicht2_dn.jpg"), 230 driver->getTexture("../../media/irrlicht2_dn.jpg"),
231 driver->getTexture("../../media/irrlicht2_lf.jpg"), 231 driver->getTexture("../../media/irrlicht2_lf.jpg"),
232 driver->getTexture("../../media/irrlicht2_rt.jpg"), 232 driver->getTexture("../../media/irrlicht2_rt.jpg"),
233 driver->getTexture("../../media/irrlicht2_ft.jpg"), 233 driver->getTexture("../../media/irrlicht2_ft.jpg"),
234 driver->getTexture("../../media/irrlicht2_bk.jpg")); 234 driver->getTexture("../../media/irrlicht2_bk.jpg"));
235 scene::ISceneNode* skydome=smgr->addSkyDomeSceneNode(driver->getTexture("../../media/skydome.jpg"),16,8,0.95f,2.0f); 235 scene::ISceneNode* skydome=smgr->addSkyDomeSceneNode(driver->getTexture("../../media/skydome.jpg"),16,8,0.95f,2.0f);
236 236
237 driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true); 237 driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
238 238
239 // create event receiver 239 // create event receiver
240 MyEventReceiver receiver(terrain, skybox, skydome); 240 MyEventReceiver receiver(terrain, skybox, skydome);
241 device->setEventReceiver(&receiver); 241 device->setEventReceiver(&receiver);
242 242
243 /* 243 /*
244 That's it, draw everything. 244 That's it, draw everything.
245 */ 245 */
246 246
247 int lastFPS = -1; 247 int lastFPS = -1;
248 248
249 while(device->run()) 249 while(device->run())
250 if (device->isWindowActive()) 250 if (device->isWindowActive())
251 { 251 {
252 driver->beginScene(true, true, 0 ); 252 driver->beginScene(true, true, 0 );
253 253
254 smgr->drawAll(); 254 smgr->drawAll();
255 env->drawAll(); 255 env->drawAll();
256 256
257 driver->endScene(); 257 driver->endScene();
258 258
259 // display frames per second in window title 259 // display frames per second in window title
260 int fps = driver->getFPS(); 260 int fps = driver->getFPS();
261 if (lastFPS != fps) 261 if (lastFPS != fps)
262 { 262 {
263 core::stringw str = L"Terrain Renderer - Irrlicht Engine ["; 263 core::stringw str = L"Terrain Renderer - Irrlicht Engine [";
264 str += driver->getName(); 264 str += driver->getName();
265 str += "] FPS:"; 265 str += "] FPS:";
266 str += fps; 266 str += fps;
267 // Also print terrain height of current camera position 267 // Also print terrain height of current camera position
268 // We can use camera position because terrain is located at coordinate origin 268 // We can use camera position because terrain is located at coordinate origin
269 str += " Height: "; 269 str += " Height: ";
270 str += terrain->getHeight(camera->getAbsolutePosition().X, 270 str += terrain->getHeight(camera->getAbsolutePosition().X,
271 camera->getAbsolutePosition().Z); 271 camera->getAbsolutePosition().Z);
272 272
273 device->setWindowCaption(str.c_str()); 273 device->setWindowCaption(str.c_str());
274 lastFPS = fps; 274 lastFPS = fps;
275 } 275 }
276 } 276 }
277 277
278 device->drop(); 278 device->drop();
279 279
280 return 0; 280 return 0;
281} 281}
282 282
283/* 283/*
284Now you know how to use terrain in Irrlicht. 284Now you know how to use terrain in Irrlicht.
285**/ 285**/