aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/doc/html/example010.html
blob: 85289bf90afa9c12efe5634317a2d9b00ef3ef76 (plain)
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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>Irrlicht 3D Engine: Tutorial 10: Shaders</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>

</head>
<body>
<div id="top"><!-- do not remove this div! -->


<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  <td id="projectlogo"><img alt="Logo" src="irrlichtlogo.png"/></td>
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">Irrlicht 3D Engine
   
   </div>
   
  </td>
  
  
  
   
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</td>
   
  
 </tr>
 </tbody>
</table>
</div>

<!-- Generated by Doxygen 1.7.5.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="dynsections.js"></script>
</div>
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
  initNavTree('example010.html','');
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">Tutorial 10: Shaders </div>  </div>
</div>
<div class="contents">
<div class="textblock"><div class="image">
<img src="010shot.jpg" alt="010shot.jpg"/>
</div>
 <p>This tutorial shows how to use shaders for D3D8, D3D9, OpenGL, and Cg with the engine and how to create new material types with them. It also shows how to disable the generation of mipmaps at texture loading, and how to use text scene nodes.</p>
<p>This tutorial does not explain how shaders work. I would recommend to read the D3D, OpenGL, or Cg documentation, to search a tutorial, or to read a book about this.</p>
<p>At first, we need to include all headers and do the stuff we always do, like in nearly all other tutorials: </p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;<a class="code" href="irrlicht_8h.html" title="Main header file of the irrlicht, the only file needed to include.">irrlicht.h</a>&gt;</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>
<span class="preprocessor">#include &quot;<a class="code" href="driver_choice_8h.html">driverChoice.h</a>&quot;</span>

<span class="keyword">using namespace </span>irr;

<span class="preprocessor">#ifdef _MSC_VER</span>
<span class="preprocessor"></span><span class="preprocessor">#pragma comment(lib, &quot;Irrlicht.lib&quot;)</span>
<span class="preprocessor">#endif</span>
</pre></div><p>Because we want to use some interesting shaders in this tutorials, we need to set some data for them to make them able to compute nice colors. In this example, we'll use a simple vertex shader which will calculate the color of the vertex based on the position of the camera. For this, the shader needs the following data: The inverted world matrix for transforming the normal, the clip matrix for transforming the position, the camera position and the world position of the object for the calculation of the angle of light, and the color of the light. To be able to tell the shader all this data every frame, we have to derive a class from the IShaderConstantSetCallBack interface and override its only method, namely OnSetConstants(). This method will be called every time the material is set. The method setVertexShaderConstant() of the IMaterialRendererServices interface is used to set the data the shader needs. If the user chose to use a High Level shader language like HLSL instead of Assembler in this example, you have to set the variable name as parameter instead of the register index. </p>
<div class="fragment"><pre class="fragment">IrrlichtDevice* device = 0;
<span class="keywordtype">bool</span> UseHighLevelShaders = <span class="keyword">false</span>;
<span class="keywordtype">bool</span> UseCgShaders = <span class="keyword">false</span>;

<span class="keyword">class </span>MyShaderCallBack : <span class="keyword">public</span> video::IShaderConstantSetCallBack
{
<span class="keyword">public</span>:

    <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnSetConstants(video::IMaterialRendererServices* services,
            <a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> userData)
    {
        video::IVideoDriver* driver = services-&gt;getVideoDriver();

        <span class="comment">// set inverted world matrix</span>
        <span class="comment">// if we are using highlevel shaders (the user can select this when</span>
        <span class="comment">// starting the program), we must set the constants by name.</span>

        <a class="code" href="namespaceirr_1_1core.html#a73fa92e638c5ca97efd72da307cc9b65" title="Typedef for f32 matrix.">core::matrix4</a> invWorld = driver-&gt;getTransform(<a class="code" href="namespaceirr_1_1video.html#a15b57657a320243be03ae6f66fcff43da843cf42adb3fa9caf61c9e228cf14e85" title="World transformation.">video::ETS_WORLD</a>);
        invWorld.makeInverse();

        <span class="keywordflow">if</span> (UseHighLevelShaders)
            services-&gt;setVertexShaderConstant(<span class="stringliteral">&quot;mInvWorld&quot;</span>, invWorld.pointer(), 16);
        <span class="keywordflow">else</span>
            services-&gt;setVertexShaderConstant(invWorld.pointer(), 0, 4);

        <span class="comment">// set clip matrix</span>

        <a class="code" href="namespaceirr_1_1core.html#a73fa92e638c5ca97efd72da307cc9b65" title="Typedef for f32 matrix.">core::matrix4</a> worldViewProj;
        worldViewProj = driver-&gt;getTransform(<a class="code" href="namespaceirr_1_1video.html#a15b57657a320243be03ae6f66fcff43dae7ec186418508c67a7562af012d7b63f" title="Projection transformation.">video::ETS_PROJECTION</a>);
        worldViewProj *= driver-&gt;getTransform(<a class="code" href="namespaceirr_1_1video.html#a15b57657a320243be03ae6f66fcff43da152f4262d5874186e0288934c7d31e14" title="View transformation.">video::ETS_VIEW</a>);
        worldViewProj *= driver-&gt;getTransform(<a class="code" href="namespaceirr_1_1video.html#a15b57657a320243be03ae6f66fcff43da843cf42adb3fa9caf61c9e228cf14e85" title="World transformation.">video::ETS_WORLD</a>);

        <span class="keywordflow">if</span> (UseHighLevelShaders)
            services-&gt;setVertexShaderConstant(<span class="stringliteral">&quot;mWorldViewProj&quot;</span>, worldViewProj.pointer(), 16);
        <span class="keywordflow">else</span>
            services-&gt;setVertexShaderConstant(worldViewProj.pointer(), 4, 4);

        <span class="comment">// set camera position</span>

        <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a> pos = device-&gt;getSceneManager()-&gt;
            getActiveCamera()-&gt;getAbsolutePosition();

        <span class="keywordflow">if</span> (UseHighLevelShaders)
            services-&gt;setVertexShaderConstant(<span class="stringliteral">&quot;mLightPos&quot;</span>, reinterpret_cast&lt;f32*&gt;(&amp;pos), 3);
        <span class="keywordflow">else</span>
            services-&gt;setVertexShaderConstant(reinterpret_cast&lt;f32*&gt;(&amp;pos), 8, 1);

        <span class="comment">// set light color</span>

        video::SColorf col(0.0f,1.0f,1.0f,0.0f);

        <span class="keywordflow">if</span> (UseHighLevelShaders)
            services-&gt;setVertexShaderConstant(<span class="stringliteral">&quot;mLightColor&quot;</span>,
                    reinterpret_cast&lt;f32*&gt;(&amp;col), 4);
        <span class="keywordflow">else</span>
            services-&gt;setVertexShaderConstant(reinterpret_cast&lt;f32*&gt;(&amp;col), 9, 1);

        <span class="comment">// set transposed world matrix</span>

        <a class="code" href="namespaceirr_1_1core.html#a73fa92e638c5ca97efd72da307cc9b65" title="Typedef for f32 matrix.">core::matrix4</a> world = driver-&gt;getTransform(<a class="code" href="namespaceirr_1_1video.html#a15b57657a320243be03ae6f66fcff43da843cf42adb3fa9caf61c9e228cf14e85" title="World transformation.">video::ETS_WORLD</a>);
        world = world.getTransposed();

        <span class="keywordflow">if</span> (UseHighLevelShaders)
        {
            services-&gt;setVertexShaderConstant(<span class="stringliteral">&quot;mTransWorld&quot;</span>, world.pointer(), 16);

            <span class="comment">// set texture, for textures you can use both an int and a float setPixelShaderConstant interfaces (You need it only for an OpenGL driver).</span>
            <a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> TextureLayerID = 0;
            <span class="keywordflow">if</span> (UseHighLevelShaders)
                services-&gt;setPixelShaderConstant(<span class="stringliteral">&quot;myTexture&quot;</span>, &amp;TextureLayerID, 1);
        }
        <span class="keywordflow">else</span>
            services-&gt;setVertexShaderConstant(world.pointer(), 10, 4);
    }
};
</pre></div><p>The next few lines start up the engine just like in most other tutorials before. But in addition, we ask the user if he wants to use high level shaders in this example, if he selected a driver which is capable of doing so. </p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> main()
{
    <span class="comment">// ask user for driver</span>
    <a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType=driverChoiceConsole();
    <span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0ae685cada50f8c100403134d932d0414c" title="No driver, just for counting the elements.">video::EDT_COUNT</a>)
        <span class="keywordflow">return</span> 1;

    <span class="comment">// ask the user if we should use high level shaders for this example</span>
    <span class="keywordflow">if</span> (driverType == <a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0a4691ca314f9018f508dcf2c57dcaacec" title="Direct3D 9 device, only available on Win32 platforms.">video::EDT_DIRECT3D9</a> ||
         driverType == <a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0a2715182a79f1cb8e2826fd68a8150a53" title="OpenGL device, available on most platforms.">video::EDT_OPENGL</a>)
    {
        <span class="keywordtype">char</span> i;
        printf(<span class="stringliteral">&quot;Please press &#39;y&#39; if you want to use high level shaders.\n&quot;</span>);
        std::cin &gt;&gt; i;
        <span class="keywordflow">if</span> (i == <span class="charliteral">&#39;y&#39;</span>)
        {
            UseHighLevelShaders = <span class="keyword">true</span>;
            printf(<span class="stringliteral">&quot;Please press &#39;y&#39; if you want to use Cg shaders.\n&quot;</span>);
            std::cin &gt;&gt; i;
            <span class="keywordflow">if</span> (i == <span class="charliteral">&#39;y&#39;</span>)
                UseCgShaders = <span class="keyword">true</span>;
        }
    }

    <span class="comment">// create device</span>
    device = <a class="code" href="namespaceirr.html#abaf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.">createDevice</a>(driverType, core::dimension2d&lt;u32&gt;(640, 480));

    <span class="keywordflow">if</span> (device == 0)
        <span class="keywordflow">return</span> 1; <span class="comment">// could not create selected driver.</span>

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

    <span class="comment">// Make sure we don&#39;t try Cg without support for it</span>
    <span class="keywordflow">if</span> (UseCgShaders &amp;&amp; !driver-&gt;queryFeature(<a class="code" href="namespaceirr_1_1video.html#a57b1721e42a79c5dcf8e830e3621e08fa92cc732f2742ef93d0d389a72bc1c236" title="Support for NVidia&#39;s CG shader language.">video::EVDF_CG</a>))
    {
        printf(<span class="stringliteral">&quot;Warning: No Cg support, disabling.\n&quot;</span>);
        UseCgShaders=<span class="keyword">false</span>;
    }
</pre></div><p>Now for the more interesting parts. If we are using Direct3D, we want to load vertex and pixel shader programs, if we have OpenGL, we want to use ARB fragment and vertex programs. I wrote the corresponding programs down into the files d3d8.ps, d3d8.vs, d3d9.ps, d3d9.vs, opengl.ps and opengl.vs. We only need the right filenames now. This is done in the following switch. Note, that it is not necessary to write the shaders into text files, like in this example. You can even write the shaders directly as strings into the cpp source file, and use later addShaderMaterial() instead of addShaderMaterialFromFiles(). </p>
<div class="fragment"><pre class="fragment">    <a class="code" href="namespaceirr_1_1io.html#ab1bdc45edb3f94d8319c02bc0f840ee1" title="Type used for all file system related strings.">io::path</a> vsFileName; <span class="comment">// filename for the vertex shader</span>
    <a class="code" href="namespaceirr_1_1io.html#ab1bdc45edb3f94d8319c02bc0f840ee1" title="Type used for all file system related strings.">io::path</a> psFileName; <span class="comment">// filename for the pixel shader</span>

    <span class="keywordflow">switch</span>(driverType)
    {
    <span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0a8cc3807f6f28404f3424ad7e31b3142f" title="Direct3D8 device, only available on Win32 platforms.">video::EDT_DIRECT3D8</a>:
        psFileName = <span class="stringliteral">&quot;../../media/d3d8.psh&quot;</span>;
        vsFileName = <span class="stringliteral">&quot;../../media/d3d8.vsh&quot;</span>;
        <span class="keywordflow">break</span>;
    <span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0a4691ca314f9018f508dcf2c57dcaacec" title="Direct3D 9 device, only available on Win32 platforms.">video::EDT_DIRECT3D9</a>:
        <span class="keywordflow">if</span> (UseHighLevelShaders)
        {
            <span class="comment">// Cg can also handle this syntax</span>
            psFileName = <span class="stringliteral">&quot;../../media/d3d9.hlsl&quot;</span>;
            vsFileName = psFileName; <span class="comment">// both shaders are in the same file</span>
        }
        <span class="keywordflow">else</span>
        {
            psFileName = <span class="stringliteral">&quot;../../media/d3d9.psh&quot;</span>;
            vsFileName = <span class="stringliteral">&quot;../../media/d3d9.vsh&quot;</span>;
        }
        <span class="keywordflow">break</span>;

    <span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0a2715182a79f1cb8e2826fd68a8150a53" title="OpenGL device, available on most platforms.">video::EDT_OPENGL</a>:
        <span class="keywordflow">if</span> (UseHighLevelShaders)
        {
            <span class="keywordflow">if</span> (!UseCgShaders)
            {
                psFileName = <span class="stringliteral">&quot;../../media/opengl.frag&quot;</span>;
                vsFileName = <span class="stringliteral">&quot;../../media/opengl.vert&quot;</span>;
            }
            <span class="keywordflow">else</span>
            {
                <span class="comment">// Use HLSL syntax for Cg</span>
                psFileName = <span class="stringliteral">&quot;../../media/d3d9.hlsl&quot;</span>;
                vsFileName = psFileName; <span class="comment">// both shaders are in the same file</span>
            }
        }
        <span class="keywordflow">else</span>
        {
            psFileName = <span class="stringliteral">&quot;../../media/opengl.psh&quot;</span>;
            vsFileName = <span class="stringliteral">&quot;../../media/opengl.vsh&quot;</span>;
        }
        <span class="keywordflow">break</span>;
    }
</pre></div><p>In addition, we check if the hardware and the selected renderer is capable of executing the shaders we want. If not, we simply set the filename string to 0. This is not necessary, but useful in this example: For example, if the hardware is able to execute vertex shaders but not pixel shaders, we create a new material which only uses the vertex shader, and no pixel shader. Otherwise, if we would tell the engine to create this material and the engine sees that the hardware wouldn't be able to fulfill the request completely, it would not create any new material at all. So in this example you would see at least the vertex shader in action, without the pixel shader. </p>
<div class="fragment"><pre class="fragment">    <span class="keywordflow">if</span> (!driver-&gt;queryFeature(<a class="code" href="namespaceirr_1_1video.html#a57b1721e42a79c5dcf8e830e3621e08fae3c30045e54cd02efdb3e67eff12664f" title="Is Pixel Shader 1.1 supported?">video::EVDF_PIXEL_SHADER_1_1</a>) &amp;&amp;
        !driver-&gt;queryFeature(<a class="code" href="namespaceirr_1_1video.html#a57b1721e42a79c5dcf8e830e3621e08fa85cee74794874723bd275226ad0ded76" title="Are ARB fragment programs v1.0 supported?">video::EVDF_ARB_FRAGMENT_PROGRAM_1</a>))
    {
        device-&gt;getLogger()-&gt;log(<span class="stringliteral">&quot;WARNING: Pixel shaders disabled &quot;</span>\
            <span class="stringliteral">&quot;because of missing driver/hardware support.&quot;</span>);
        psFileName = <span class="stringliteral">&quot;&quot;</span>;
    }

    <span class="keywordflow">if</span> (!driver-&gt;queryFeature(<a class="code" href="namespaceirr_1_1video.html#a57b1721e42a79c5dcf8e830e3621e08fae85fe645c5839d5b015047abf5fff3e6" title="Is Vertex Shader 1.1 supported?">video::EVDF_VERTEX_SHADER_1_1</a>) &amp;&amp;
        !driver-&gt;queryFeature(<a class="code" href="namespaceirr_1_1video.html#a57b1721e42a79c5dcf8e830e3621e08fa1eca6110e4fd3ee59e1aee60cf20e88b" title="Are ARB vertex programs v1.0 supported?">video::EVDF_ARB_VERTEX_PROGRAM_1</a>))
    {
        device-&gt;getLogger()-&gt;log(<span class="stringliteral">&quot;WARNING: Vertex shaders disabled &quot;</span>\
            <span class="stringliteral">&quot;because of missing driver/hardware support.&quot;</span>);
        vsFileName = <span class="stringliteral">&quot;&quot;</span>;
    }
</pre></div><p>Now lets create the new materials. As you maybe know from previous examples, a material type in the Irrlicht engine is set by simply changing the MaterialType value in the SMaterial struct. And this value is just a simple 32 bit value, like video::EMT_SOLID. So we only need the engine to create a new value for us which we can set there. To do this, we get a pointer to the IGPUProgrammingServices and call addShaderMaterialFromFiles(), which returns such a new 32 bit value. That's all.</p>
<p>The parameters to this method are the following: First, the names of the files containing the code of the vertex and the pixel shader. If you would use addShaderMaterial() instead, you would not need file names, then you could write the code of the shader directly as string. The following parameter is a pointer to the IShaderConstantSetCallBack class we wrote at the beginning of this tutorial. If you don't want to set constants, set this to 0. The last parameter tells the engine which material it should use as base material.</p>
<p>To demonstrate this, we create two materials with a different base material, one with EMT_SOLID and one with EMT_TRANSPARENT_ADD_COLOR. </p>
<div class="fragment"><pre class="fragment">    <span class="comment">// create materials</span>

    video::IGPUProgrammingServices* gpu = driver-&gt;getGPUProgrammingServices();
    <a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> newMaterialType1 = 0;
    <a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> newMaterialType2 = 0;

    <span class="keywordflow">if</span> (gpu)
    {
        MyShaderCallBack* mc = <span class="keyword">new</span> MyShaderCallBack();

        <span class="comment">// create the shaders depending on if the user wanted high level</span>
        <span class="comment">// or low level shaders:</span>

        <span class="keywordflow">if</span> (UseHighLevelShaders)
        {
            <span class="comment">// Choose the desired shader type. Default is the native</span>
            <span class="comment">// shader type for the driver, for Cg pass the special</span>
            <span class="comment">// enum value EGSL_CG</span>
            <span class="keyword">const</span> <a class="code" href="namespaceirr_1_1video.html#a913671e32f20f13e51336bfbe20a82a3" title="Enumeration for different types of shading languages.">video::E_GPU_SHADING_LANGUAGE</a> shadingLanguage =
                UseCgShaders ? <a class="code" href="namespaceirr_1_1video.html#a913671e32f20f13e51336bfbe20a82a3a703622fd615408677044b9ec67f5ea42" title="Cg shading language.*/.">video::EGSL_CG</a>:<a class="code" href="namespaceirr_1_1video.html#a913671e32f20f13e51336bfbe20a82a3ac65c039e1c80a430a816c450a5f30d4b" title="The default language, so HLSL for Direct3D and GLSL for OpenGL.">video::EGSL_DEFAULT</a>;

            <span class="comment">// create material from high level shaders (hlsl, glsl or cg)</span>

            newMaterialType1 = gpu-&gt;addHighLevelShaderMaterialFromFiles(
                vsFileName, <span class="stringliteral">&quot;vertexMain&quot;</span>, <a class="code" href="namespaceirr_1_1video.html#a9decae50d4dc2455e7b009f5c71b24f9a60cc4ef72d14e7192dc721bde0f07461">video::EVST_VS_1_1</a>,
                psFileName, <span class="stringliteral">&quot;pixelMain&quot;</span>, <a class="code" href="namespaceirr_1_1video.html#a07fb77e9aec681402ad376f7ef9b724ca600133dcb93a6cbdddaed1e09cc8a2cc">video::EPST_PS_1_1</a>,
                mc, <a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1a9bc471b9c18c9e2d20496004d2a2e803" title="Standard solid material.">video::EMT_SOLID</a>, 0, shadingLanguage);

            newMaterialType2 = gpu-&gt;addHighLevelShaderMaterialFromFiles(
                vsFileName, <span class="stringliteral">&quot;vertexMain&quot;</span>, <a class="code" href="namespaceirr_1_1video.html#a9decae50d4dc2455e7b009f5c71b24f9a60cc4ef72d14e7192dc721bde0f07461">video::EVST_VS_1_1</a>,
                psFileName, <span class="stringliteral">&quot;pixelMain&quot;</span>, <a class="code" href="namespaceirr_1_1video.html#a07fb77e9aec681402ad376f7ef9b724ca600133dcb93a6cbdddaed1e09cc8a2cc">video::EPST_PS_1_1</a>,
                mc, <a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1a1b5a814c4466aca2943ff056003a50d1" title="A transparent material.">video::EMT_TRANSPARENT_ADD_COLOR</a>, 0 , shadingLanguage);
        }
        <span class="keywordflow">else</span>
        {
            <span class="comment">// create material from low level shaders (asm or arb_asm)</span>

            newMaterialType1 = gpu-&gt;addShaderMaterialFromFiles(vsFileName,
                psFileName, mc, <a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1a9bc471b9c18c9e2d20496004d2a2e803" title="Standard solid material.">video::EMT_SOLID</a>);

            newMaterialType2 = gpu-&gt;addShaderMaterialFromFiles(vsFileName,
                psFileName, mc, <a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1a1b5a814c4466aca2943ff056003a50d1" title="A transparent material.">video::EMT_TRANSPARENT_ADD_COLOR</a>);
        }

        mc-&gt;drop();
    }
</pre></div><p>Now it's time for testing the materials. We create a test cube and set the material we created. In addition, we add a text scene node to the cube and a rotation animator to make it look more interesting and important. </p>
<div class="fragment"><pre class="fragment">    <span class="comment">// create test scene node 1, with the new created material type 1</span>

    scene::ISceneNode* node = smgr-&gt;addCubeSceneNode(50);
    node-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,0,0));
    node-&gt;setMaterialTexture(0, driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/wall.bmp&quot;</span>));
    node-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3acea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">video::EMF_LIGHTING</a>, <span class="keyword">false</span>);
    node-&gt;setMaterialType((<a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1" title="Abstracted and easy to use fixed function/programmable pipeline material modes.">video::E_MATERIAL_TYPE</a>)newMaterialType1);

    smgr-&gt;addTextSceneNode(gui-&gt;getBuiltInFont(),
            L<span class="stringliteral">&quot;PS &amp; VS &amp; EMT_SOLID&quot;</span>,
            video::SColor(255,255,255,255), node);

    scene::ISceneNodeAnimator* anim = smgr-&gt;createRotationAnimator(
            <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,0.3f,0));
    node-&gt;addAnimator(anim);
    anim-&gt;drop();
</pre></div><p>Same for the second cube, but with the second material we created. </p>
<div class="fragment"><pre class="fragment">    <span class="comment">// create test scene node 2, with the new created material type 2</span>

    node = smgr-&gt;addCubeSceneNode(50);
    node-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,-10,50));
    node-&gt;setMaterialTexture(0, driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/wall.bmp&quot;</span>));
    node-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3acea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">video::EMF_LIGHTING</a>, <span class="keyword">false</span>);
    node-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3ab9cbb5be402278cf0276da84acd3da14" title="Flag for blend operation.">video::EMF_BLEND_OPERATION</a>, <span class="keyword">true</span>);
    node-&gt;setMaterialType((<a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1" title="Abstracted and easy to use fixed function/programmable pipeline material modes.">video::E_MATERIAL_TYPE</a>)newMaterialType2);

    smgr-&gt;addTextSceneNode(gui-&gt;getBuiltInFont(),
            L<span class="stringliteral">&quot;PS &amp; VS &amp; EMT_TRANSPARENT&quot;</span>,
            video::SColor(255,255,255,255), node);

    anim = smgr-&gt;createRotationAnimator(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,0.3f,0));
    node-&gt;addAnimator(anim);
    anim-&gt;drop();
</pre></div><p>Then we add a third cube without a shader on it, to be able to compare the cubes. </p>
<div class="fragment"><pre class="fragment">    <span class="comment">// add a scene node with no shader</span>

    node = smgr-&gt;addCubeSceneNode(50);
    node-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,50,25));
    node-&gt;setMaterialTexture(0, driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/wall.bmp&quot;</span>));
    node-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3acea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">video::EMF_LIGHTING</a>, <span class="keyword">false</span>);
    smgr-&gt;addTextSceneNode(gui-&gt;getBuiltInFont(), L<span class="stringliteral">&quot;NO SHADER&quot;</span>,
        video::SColor(255,255,255,255), node);
</pre></div><p>And last, we add a skybox and a user controlled camera to the scene. For the skybox textures, we disable mipmap generation, because we don't need mipmaps on it. </p>
<div class="fragment"><pre class="fragment">    <span class="comment">// add a nice skybox</span>

    driver-&gt;setTextureCreationFlag(<a class="code" href="namespaceirr_1_1video.html#acaf6f7414534f7d62bff18c5bf11876fa288b302e9d4faaba80c7796c7bc1682c">video::ETCF_CREATE_MIP_MAPS</a>, <span class="keyword">false</span>);

    smgr-&gt;addSkyBoxSceneNode(
        driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_up.jpg&quot;</span>),
        driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_dn.jpg&quot;</span>),
        driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_lf.jpg&quot;</span>),
        driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_rt.jpg&quot;</span>),
        driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_ft.jpg&quot;</span>),
        driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_bk.jpg&quot;</span>));

    driver-&gt;setTextureCreationFlag(<a class="code" href="namespaceirr_1_1video.html#acaf6f7414534f7d62bff18c5bf11876fa288b302e9d4faaba80c7796c7bc1682c">video::ETCF_CREATE_MIP_MAPS</a>, <span class="keyword">true</span>);

    <span class="comment">// add a camera and disable the mouse cursor</span>

    scene::ICameraSceneNode* cam = smgr-&gt;addCameraSceneNodeFPS();
    cam-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-100,50,100));
    cam-&gt;setTarget(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,0,0));
    device-&gt;getCursorControl()-&gt;setVisible(<span class="keyword">false</span>);
</pre></div><p>Now draw everything. That's all. </p>
<div class="fragment"><pre class="fragment">    <span class="keywordtype">int</span> lastFPS = -1;

    <span class="keywordflow">while</span>(device-&gt;run())
        <span class="keywordflow">if</span> (device-&gt;isWindowActive())
    {
        driver-&gt;beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, video::SColor(255,0,0,0));
        smgr-&gt;drawAll();
        driver-&gt;endScene();

        <span class="keywordtype">int</span> fps = driver-&gt;getFPS();

        <span class="keywordflow">if</span> (lastFPS != fps)
        {
            <a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a> str = L<span class="stringliteral">&quot;Irrlicht Engine - Vertex and pixel shader example [&quot;</span>;
            str += driver-&gt;getName();
            str += <span class="stringliteral">&quot;] FPS:&quot;</span>;
            str += fps;

            device-&gt;setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }

    device-&gt;drop();

    <span class="keywordflow">return</span> 0;
}
</pre></div><p>Compile and run this, and I hope you have fun with your new little shader writing tool :). </p>
</div></div>
</div>
  <div id="nav-path" class="navpath">
    <ul>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark">&#160;</span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark">&#160;</span>Defines</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>


    <li class="footer">
<a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht 
Engine</a> Documentation &copy; 2003-2012 by Nikolaus Gebhardt. Generated on Tue Nov 6 2012 11:06:01 for Irrlicht 3D Engine by
<a href="http://www.doxygen.org/index.html" target="_blank">Doxygen</a> 1.7.5.1 </li>
   </ul>
 </div>


</body>
</html>