diff options
author | David Walter Seikel | 2013-01-13 17:24:39 +1000 |
---|---|---|
committer | David Walter Seikel | 2013-01-13 17:24:39 +1000 |
commit | 393b5cd1dc438872af89d334ef6e5fcc59f27d47 (patch) | |
tree | 6a14521219942a08a1b95cb2f5a923a9edd60f63 /libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp | |
parent | Add a note about rasters suggested start up code. (diff) | |
download | SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.zip SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.tar.gz SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.tar.bz2 SledjHamr-393b5cd1dc438872af89d334ef6e5fcc59f27d47.tar.xz |
Added Irrlicht 1.8, but without all the Windows binaries.
Diffstat (limited to 'libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp b/libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp new file mode 100644 index 0000000..d829244 --- /dev/null +++ b/libraries/irrlicht-1.8/examples/12.TerrainRendering/main.cpp | |||
@@ -0,0 +1,285 @@ | |||
1 | /** Example 012 Terrain Rendering | ||
2 | |||
3 | This tutorial will briefly show how to use the terrain renderer of Irrlicht. It | ||
4 | will also show the terrain renderer triangle selector to be able to do | ||
5 | collision detection with terrain. | ||
6 | |||
7 | Note that the Terrain Renderer in Irrlicht is based on Spintz' | ||
8 | GeoMipMapSceneNode, lots of thanks go to him. DeusXL provided a new elegant | ||
9 | simple solution for building larger area on small heightmaps -> terrain | ||
10 | smoothing. | ||
11 | |||
12 | In the beginning there is nothing special. We include the needed header files | ||
13 | and create an event listener to listen if the user presses a key: The 'W' key | ||
14 | switches to wireframe mode, the 'P' key to pointcloud mode, and the 'D' key | ||
15 | toggles between solid and detail mapped material. | ||
16 | */ | ||
17 | #include <irrlicht.h> | ||
18 | #include "driverChoice.h" | ||
19 | |||
20 | using namespace irr; | ||
21 | |||
22 | #ifdef _MSC_VER | ||
23 | #pragma comment(lib, "Irrlicht.lib") | ||
24 | #endif | ||
25 | |||
26 | |||
27 | class MyEventReceiver : public IEventReceiver | ||
28 | { | ||
29 | public: | ||
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 | |||
77 | private: | ||
78 | scene::ISceneNode* Terrain; | ||
79 | scene::ISceneNode* Skybox; | ||
80 | scene::ISceneNode* Skydome; | ||
81 | bool showBox; | ||
82 | bool showDebug; | ||
83 | }; | ||
84 | |||
85 | |||
86 | /* | ||
87 | The start of the main function starts like in most other example. We ask the | ||
88 | user for the desired renderer and start it up. This time with the advanced | ||
89 | parameter handling. | ||
90 | */ | ||
91 | int 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 | /* | ||
284 | Now you know how to use terrain in Irrlicht. | ||
285 | **/ | ||