1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
<html>
<head>
<title>Irrlicht Engine Tutorial</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
<br>
<table width="95%" border="0" cellspacing="0" cellpadding="2" align="center">
<tr>
<td bgcolor="#666699" width="10"><b><a href="http://irrlicht.sourceforge.net" target="_blank"><img src="../../media/irrlichtlogo.jpg" width="88" height="31" border="0"></a></b></td>
<td bgcolor="#666699" width="100%">
<div align="center">
<div align="left"><b><font color="#FFFFFF">Tutorial 13. Render to Texture</font></b></div>
</div>
</td>
</tr>
<tr bgcolor="#eeeeff">
<td height="90" colspan="2">
<div align="left">
<p> This tutorial shows how to render to a texture using Irrlicht. Render
to texture is a feature with which it is possible to create nice special
effects. In addition, this tutorial shows how to enable specular highlights.</p>
<p>The program which is described here will look like this:</p>
<p align="center"><img src="../../media/013shot.jpg" width="256" height="200"><br>
</p>
</div>
</td>
</tr>
</table>
<br>
<table width="95%" border="0" cellspacing="0" cellpadding="2" align="center">
<tr>
<td bgcolor="#666699"> <b><font color="#FFFFFF">Lets start!</font></b></td>
</tr>
<tr>
<td height="90" bgcolor="#eeeeff" valign="top"> <div align="left">
<div align="left">
<p>In the beginning, everything as usual. Include the needed headers,
ask the user for the rendering driver, create the Irrlicht Device:</p>
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
<tr>
<td><pre>#include <irrlicht.h>
#include <iostream>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
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"\<br> " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\<br> " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\<br> " (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)<br> {<br> case 'a': driverType = video::EDT_DIRECT3D9;break;<br> case 'b': driverType = video::EDT_DIRECT3D8;break;<br> case 'c': driverType = video::EDT_OPENGL; break;<br> case 'd': driverType = video::EDT_SOFTWARE; break;<br> case 'e': driverType = video::EDT_BURNINGSVIDEO;break;<br> case 'f': driverType = video::EDT_NULL; break;<br> default: return 1;<br> }
// create device and exit if creation failed
IrrlichtDevice *device =
createDevice(driverType, core::dimension2d<s32>(640, 480),
16, false, false);
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* env = device->getGUIEnvironment();</pre></td>
</tr>
</table>
<p>Now, we load an animated mesh to be displayed. As in most examples,
we'll take the fairy md2 model. The difference here: We set the shininess<br>
of the model to a value other than 0 which is the default value. This
enables specular highlights on the model if dynamic lighting is on.
The value influences the size of the highlights.</p>
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
<tr>
<td><pre>// load and display animated fairy mesh
scene::IAnimatedMeshSceneNode* fairy = smgr->addAnimatedMeshSceneNode(
smgr->getMesh("../../media/faerie.md2"));
if (fairy)
{
fairy->setMaterialTexture(0, driver->getTexture("../../media/faerie2.bmp")); // set diffuse texture
fairy->setMaterialFlag(video::EMF_LIGHTING, true); // enable dynamic lighting
fairy->getMaterial(0).Shininess = 20.0f; // set size of specular highlights
fairy->setPosition(core::vector3df(-10,0,-100));
}</pre></td>
</tr>
</table>
<p> To make specular highlights appear on the model, we need a dynamic
light in the scene. We add one directly in vicinity of the model.
In addition, to make the model not that dark, we set the ambient light
to gray. </p>
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
<tr>
<td><pre>
// add white light
scene::ILightSceneNode* light = smgr->addLightSceneNode(0,
core::vector3df(-15,5,-105), video::SColorf(1.0f, 1.0f, 1.0f));
// set ambient light
driver->setAmbientLight(video::SColor(0,60,60,60));</pre></td>
</tr>
</table>
<p>The next is just some standard stuff: Add a user controlled camera
to the scene, disable mouse cursor, and add a test cube and let it
rotate to make the scene more interesting.</p>
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
<tr>
<td><pre>
// add fps camera
scene::ICameraSceneNode* fpsCamera = smgr->addCameraSceneNodeFPS();
fpsCamera->setPosition(core::vector3df(-50,50,-150));
// disable mouse cursor
device->getCursorControl()->setVisible(false);
// create test cube
scene::ISceneNode* test = smgr->addCubeSceneNode(60);
// let the cube rotate and set some light settings
scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator(
core::vector3df(0.3f, 0.3f,0));
test->setPosition(core::vector3df(-100,0,-100));
test->setMaterialFlag(video::EMF_LIGHTING, false); // disable dynamic lighting
test->addAnimator(anim);
anim->drop();
// set window caption
device->setWindowCaption(L"Irrlicht Engine - Render to Texture and Specular Highlights example");</pre></td>
</tr>
</table>
<p> To test out the render to texture feature, we need a render target
texture. These are not like standard textures, but need to be created
first. To create one, we call IVideoDriver::createRenderTargetTexture()
and specify the size of the texture. Please don't use sizes bigger
than the frame buffer for this, because the render target shares the
zbuffer with the frame buffer. And because we want to render the scene
not from the user camera into the texture, we add another, fixed camera
to the scene. But before we do all this, we check if the current running
driver is able to render to textures. If it is not, we simply display
a warning text.</p>
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
<tr>
<td><pre>// create render target
video::ITexture* rt = 0;
scene::ICameraSceneNode* fixedCam = 0;
if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
{
rt = driver->createRenderTargetTexture(core::dimension2d<s32>(256,256));
test->setMaterialTexture(0, rt); // set material of cube to render target
// add fixed camera
fixedCam = smgr->addCameraSceneNode(0, core::vector3df(10,10,-80),
core::vector3df(-10,10,-100));
}
else
{
// create problem text
gui::IGUISkin* skin = env->getSkin();
gui::IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");
if (font)
skin->setFont(font);
gui::IGUIStaticText* text = env->addStaticText(
L"Your hardware or this renderer is not able to use the "\
L"render to texture feature. RTT Disabled.",
core::rect<s32>(150,20,470,60));
text->setOverrideColor(video::SColor(100,255,255,255));
}</pre></td>
</tr>
</table>
<p> Nearly finished. Now we need to draw everything. Every frame, we
draw the scene twice. Once from the fixed camera into the render target
texture and once as usual. When rendering into the render target,
we need to disable the visibilty of the test cube, because it has
the render target texture applied to it.<br>
That's, wasn't quite complicated I hope. :)</p>
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
<tr>
<td><pre>while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0);
if (rt)
{
// draw scene into render target
// set render target texture
driver->setRenderTarget(rt, true, true, video::SColor(0,0,0,255));
// make cube invisible and set fixed camera as active camera
test->setVisible(false);
smgr->setActiveCamera(fixedCam);
// draw whole scene into render buffer
smgr->drawAll();
// set back old render target
driver->setRenderTarget(0);
// make the cube visible and set the user controlled camera as active one
test->setVisible(true);
smgr->setActiveCamera(fpsCamera);
}
// draw scene normally
smgr->drawAll();
env->drawAll();
driver->endScene();
}
if (rt)
rt->drop(); // drop render target because we created if with a create() method
device->drop(); // drop device
return 0;
}
</pre></td>
</tr>
</table>
<p> </p></div>
</div>
</td>
</tr>
</table>
<p> </p>
</body>
</html>
|