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