~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to examples/10.Shaders/tutorial.html

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<html>
 
2
<head>
 
3
<title>Irrlicht Engine Tutorial</title>
 
4
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 
5
</head>
 
6
 
 
7
<body bgcolor="#FFFFFF" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
 
8
<br>
 
9
<table width="95%" border="0" cellspacing="0" cellpadding="2" align="center">
 
10
  <tr> 
 
11
    <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>
 
12
    <td bgcolor="#666699" width="100%">
 
13
<div align="center">
 
14
        <div align="left"><b><font color="#FFFFFF">Tutorial 10. Shaders</font></b></div>
 
15
      </div>
 
16
      </td>
 
17
  </tr>
 
18
  <tr bgcolor="#eeeeff"> 
 
19
    <td height="90" colspan="2"> 
 
20
      <div align="left"> 
 
21
        <p> This tutorial shows how to use shaders for D3D8, D3D9 and OpenGL with 
 
22
          the engine and how to create new material types with them. It also shows 
 
23
          how to disable the generation of mipmaps at texture loading, and how 
 
24
          to use text scene nodes.</p>
 
25
        <p>This tutorial does not explain how shaders work. I would recommend 
 
26
          to read the D3D or OpenGL documentation, to search a tutorial, or to 
 
27
          read a book about this.</p>
 
28
        <p>The program which is described here will look like this:</p>
 
29
        <p align="center"><img src="../../media/010shot.jpg" width="260" height="203"><br>
 
30
        </p>
 
31
      </div>
 
32
    </td>
 
33
  </tr>
 
34
</table>
 
35
<br>
 
36
<table width="95%" border="0" cellspacing="0" cellpadding="2" align="center">
 
37
  <tr> 
 
38
    <td bgcolor="#666699"> <b><font color="#FFFFFF">Lets start!</font></b></td>
 
39
  </tr>
 
40
  <tr> 
 
41
    <td height="90" bgcolor="#eeeeff" valign="top"> <div align="left"> 
 
42
        <div align="left"> 
 
43
          <p>At first, we need to include all headers and do the stuff we always 
 
44
            do, like in nearly all other tutorials:</p>
 
45
          <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
46
            <tr> 
 
47
              <td> <pre>#include &lt;irrlicht.h&gt;<br>#include &lt;iostream&gt;<br><br>using namespace irr;<br><br>#pragma comment(lib, &quot;Irrlicht.lib&quot;)<br></pre></td>
 
48
            </tr>
 
49
          </table>
 
50
          <p>Because we want to use some interesting shaders in this tutorials, 
 
51
            we need to set some data for them to make them able to compute nice 
 
52
            colors. In this example, we'll use a simple vertex shader which will 
 
53
            calculate the color of the vertex based on the position of the camera. 
 
54
            For this, the shader needs the following data: The inverted world 
 
55
            matrix for transforming the normal, the clip matrix for transforming 
 
56
            the position, the camera position and the world position of the object 
 
57
            for the calculation of the angle of light, and the color of the light. 
 
58
            To be able to tell the shader all this data every frame, we have to 
 
59
            derive a class from the IShaderConstantSetCallBack interface and override 
 
60
            its only method, namely OnSetConstants(). This method will be called 
 
61
            every time the material is set. <br>
 
62
            The method setVertexShaderConstant() of the IMaterialRendererServices 
 
63
            interface is used to set the data the shader needs. If the user chose 
 
64
            to use a High Level shader language like HLSL instead of Assembler 
 
65
            in this example, you have to set the variable name as parameter instead 
 
66
            of the register index.</p>
 
67
          <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
68
            <tr> 
 
69
              <td> <pre>IrrlichtDevice* device = 0;<br>bool UseHighLevelShaders = false;<br><br>class MyShaderCallBack : public video::IShaderConstantSetCallBack<br>{<br>public:
 
70
<br>  virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)<br>  {<br>    video::IVideoDriver* driver = services-&gt;getVideoDriver();<br><br>    <font color="#006600">// set inverted world matrix<br>    // if we are using highlevel shaders (the user can select this when<br>    // starting the program), we must set the constants by name.</font><br>    core::matrix4 invWorld = driver-&gt;getTransform(video::ETS_WORLD);<br>    invWorld.makeInverse();<br><br>    if (UseHighLevelShaders)<br>       services-&gt;setVertexShaderConstant(&quot;mInvWorld&quot;, &amp;invWorld.M[0], 16);<br>    else<br>       services-&gt;setVertexShaderConstant(&amp;invWorld.M[0], 0, 4);<br><font color="#006600"><br>    // set clip matrix<br></font>    core::matrix4 worldViewProj;<br>    worldViewProj = driver-&gt;getTransform(video::ETS_PROJECTION);                     <br>    worldViewProj *= driver-&gt;getTransform(video::ETS_VIEW);<br>    worldViewProj *= driver-&gt;getTransform(video::ETS_WORLD);<br><br>    if (UseHighLevelShaders)<br>       services-&gt;setVertexShaderConstant(&quot;mWorldViewProj&quot;, &amp;worldViewProj.M[0], 16);<br>    else<br>       services-&gt;setVertexShaderConstant(&amp;worldViewProj.M[0], 4, 4);<br>               <br><font color="#006600">    </font><font color="#006600">// set camera position<br></font>    core::vector3df pos = device-&gt;getSceneManager()-&gt;<br>    getActiveCamera()-&gt;getAbsolutePosition();<br><br>    if (UseHighLevelShaders)<br>      services-&gt;setVertexShaderConstant(&quot;mLightPos&quot;, reinterpret_cast&lt;f32*&gt;(&amp;pos), 3);<br>    else<br>      services-&gt;setVertexShaderConstant(reinterpret_cast&lt;f32*&gt;(&amp;pos), 8, 1);<br><br><font color="#006600">    </font><font color="#006600">// set light color <br></font>    video::SColorf col(0.0f,1.0f,1.0f,0.0f);<br><br>    if (UseHighLevelShaders)<br>      services-&gt;setVertexShaderConstant(&quot;mLightColor&quot;, reinterpret_cast&lt;f32*&gt;(&amp;col), 4);<br>    else<br>      services-&gt;setVertexShaderConstant(reinterpret_cast&lt;f32*&gt;(&amp;col), 9, 1);<br><br><font color="#006600">    </font><font color="#006600">// set transposed world matrix<br></font>    core::matrix4 world = driver-&gt;getTransform(video::ETS_WORLD);<br>    world = world.getTransposed();<br><br>    if (UseHighLevelShaders)<br>      services-&gt;setVertexShaderConstant(&quot;mTransWorld&quot;, &amp;world.M[0], 16);<br>    else<br>      services-&gt;setVertexShaderConstant(&amp;world.M[0], 10, 4);<br>    }<br>};</pre></td>
 
71
            </tr>
 
72
          </table>
 
73
          <p> The next few lines start up the engine. Just like in most other 
 
74
            tutorials before. But in addition, we ask the user if he wants this 
 
75
            example to use high level shaders if he selected a driver which is 
 
76
            capable of doing so.</p>
 
77
          <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
78
            <tr> 
 
79
              <td> <pre>int main()<br>{<br><font color="#006600">       // let user select driver type</font><br><br>   video::E_DRIVER_TYPE driverType = video::EDT_DIRECTX9;<br><br>  printf(&quot;Please select the driver you want for this example:\n&quot;\<br>           &quot; (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n&quot;\<br>               &quot; (d) Software Renderer\n (e) Apfelbaum Software Renderer\n&quot;\<br>             &quot; (f) NullDevice\n (otherKey) exit\n\n&quot;);<br><br>     char i;<br>     std::cin &gt;&gt; i;<br><br>    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>  }       <br><br><font color="#006600"> </font> <font color="#006600">// ask the user if we should use high level shaders for this example<br> </font> if (driverType == video::EDT_DIRECT3D9 ||<br>              driverType == video::EDT_OPENGL)
 
80
  {<br>      printf(&quot;<font color="#CC0000">Please press 'y' if you want to use high level shaders.\n</font>&quot;);<br>      std::cin &gt;&gt; i;<br>      if (i == 'y')<br>         UseHighLevelShaders = true;<br>       }<br><br><font color="#006600"> // create devic</font>e<br><br> device = createDevice(driverType, core::dimension2d&lt;s32&gt;(640, 480));<br><br>      if (device == 0)<br>    {<br>           printf(<font color="#CC0000">&quot;\nWas not able to create driver.\n&quot;\<br>                        &quot;Please restart and select another driver.\n&quot;</font>);<br>            getch();<br>            return 1;<br>   }       <br><br>        video::IVideoDriver* driver = device-&gt;getVideoDriver();<br>  scene::ISceneManager* smgr = device-&gt;getSceneManager();<br>  gui::IGUIEnvironment* gui = device-&gt;getGUIEnvironment();</pre></td>
 
81
            </tr>
 
82
          </table>
 
83
          <p> Now for the more interesting parts. If we are using Direct3D, we 
 
84
            want to load vertex and pixel shader programs, if we have<br>
 
85
            OpenGL, we want to use ARB fragment and vertex programs. I wrote the 
 
86
            corresponding programs down into the files d3d8.ps, d3d8.vs, d3d9.ps, 
 
87
            d3d9.vs, opengl.ps and opengl.vs. We only need the right filenames 
 
88
            now. This is done in the following switch. Note, that it is not necessary 
 
89
            to write the shaders into text files, like in this example. You can 
 
90
            even write the shaders directly as strings into the cpp source file, 
 
91
            and use later addShaderMaterial() instead of addShaderMaterialFromFiles().</p>
 
92
          <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
93
            <tr> 
 
94
              <td> <pre>        c8* vsFileName = 0<font color="#006600">; // filename for the vertex shader</font><br>  c8* psFileName = 0<font color="#006600">; // filename for the pixel shader</font><br><br>       switch(driverType)<br>  {<br>   case video::EDT_DIRECT3D8:<br>          psFileName = &quot;../../media/d3d8.psh&quot;;<br>              vsFileName = &quot;../../media/d3d8.vsh&quot;;<br>              break;<br>      case video::EDT_DIRECT3D9:<br>          if (UseHighLevelShaders)<br>            {<br>                   psFileName = &quot;../../media/d3d9.hlsl&quot;;<br>                     vsFileName = psFileName; <font color="#006600">// both shaders are in the same file</font><br>          }<br>           else<br>                {<br>                   psFileName = &quot;../../media/d3d9.psh&quot;;<br>                      vsFileName = &quot;../../media/d3d9.vsh&quot;;<br>              }<br>           break;<br>      case video::EDT_OPENGL:<br>             if (UseHighLevelShaders)<br>            {<br>                   psFileName = &quot;../../media/opengl.frag&quot;;<br>                   vsFileName = &quot;../../media/opengl.vert&quot;;<br>           }<br>           else<br>                {<br>                   psFileName = &quot;../../media/opengl.psh&quot;;<br>                    vsFileName = &quot;../../media/opengl.vsh&quot;;<br>            }<br>           break;<br>      }<br></pre> 
 
95
              </td>
 
96
            </tr>
 
97
          </table>
 
98
          <p> In addition, we check if the hardware and the selected renderer 
 
99
            is capable of executing the shaders we want. If not, we simply set 
 
100
            the filename string to 0. This is not necessary, but useful in this 
 
101
            example: For example, if the hardware is able to execute vertex shaders 
 
102
            but not pixel shaders, we create a new material which only uses the 
 
103
            vertex shader, and no pixel shader. Otherwise, if we would tell the 
 
104
            engine to create this material and the engine sees that the hardware 
 
105
            wouldn't be able to fullfill the request completely,<br>
 
106
            it would not create any new material at all. So in this example you 
 
107
            would see at least the vertex shader in action, without the pixel 
 
108
            shader.</p>
 
109
          </div>
 
110
        <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
111
          <tr> 
 
112
            <td> <pre>  if (!driver-&gt;queryFeature(video::EVDF_PIXEL_SHADER_1_1) &amp;&amp;<br>               !driver-&gt;queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))<br>       {<br>           device-&gt;getLogger()-&gt;log(&quot;WARNING: Pixel shaders disabled &quot;\<br>                        &quot;because of missing driver/hardware support.&quot;);<br>           psFileName = 0;<br>     }<br>   <br>    if (!driver-&gt;queryFeature(video::EVDF_VERTEX_SHADER_1_1) &amp;&amp;<br>              !driver-&gt;queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))<br> {<br>           device-&gt;getLogger()-&gt;log(&quot;WARNING: Vertex shaders disabled &quot;\<br>                       &quot;because of missing driver/hardware support.&quot;);<br>           vsFileName = 0;<br>     }</pre></td>
 
113
          </tr>
 
114
        </table>
 
115
        <p> Now lets create the new materials.<br>
 
116
          As you maybe know from previous examples, a material type in the Irrlicht 
 
117
          engine is set by simply changing the MaterialType value in the SMaterial 
 
118
          struct. And this value is just a simple 32 bit value, like video::EMT_SOLID. 
 
119
          So we only need the engine to create a new value for us which we can 
 
120
          set there. To do this, we get a pointer to the IGPUProgrammingServices 
 
121
          and call addShaderMaterialFromFiles(), which returns such a new 32 bit 
 
122
          value. That's all.<br>
 
123
          The parameters to this method are the following: First, the names of 
 
124
          the files containing the code of the vertex and the pixel shader.<br>
 
125
          If you would use addShaderMaterial() instead, you would not need file 
 
126
          names, then you could write the code of the shader directly as string. 
 
127
          The following parameter is a pointer to the IShaderConstantSetCallBack 
 
128
          class we wrote at the beginning of this tutorial. If you don't want 
 
129
          to set constants, set this to 0. The last paramter tells the engine 
 
130
          which material it should use as base material. <br>
 
131
          To demonstrate this, we create two materials with a different base material, 
 
132
          one with EMT_SOLID and one with EMT_TRANSPARENT_ADD_COLOR.</p>
 
133
        <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
134
          <tr> 
 
135
            <td><pre>   <font color="#006600">// create materials</font><br><br>        video::IGPUProgrammingServices* gpu = driver-&gt;getGPUProgrammingServices();<br><br>   s32 newMaterialType1 = 0;<br>   s32 newMaterialType2 = 0;<br><br>       if (gpu)<br>    {<br>           MyShaderCallBack* mc = new MyShaderCallBack();<br>      <font color="#006600">
 
136
                // create the shaders depending on if the user wanted high level<br>            // or low level shaders:</font><br><br>         if (UseHighLevelShaders)<br>            {<br><font color="#006600">                     // create material from high level shaders (hlsl or glsl)<br><br></font>                        newMaterialType1 = gpu-&gt;addHighLevelShaderMaterialFromFiles(<br>                             vsFileName,     &quot;vertexMain&quot;, video::EVST_VS_1_1,<br>                         psFileName, &quot;pixelMain&quot;, video::EPST_PS_1_1,<br>                              mc, video::EMT_SOLID);<br><br>                  newMaterialType2 = gpu-&gt;addHighLevelShaderMaterialFromFiles(<br>                             vsFileName,     &quot;vertexMain&quot;, video::EVST_VS_1_1,<br>                         psFileName, &quot;pixelMain&quot;, video::EPST_PS_1_1,<br>                              mc, video::EMT_TRANSPARENT_ADD_COLOR);<br>              }<br>           else<br>                {<br><font color="#009900">                     // create material from low level shaders (asm or arb_asm)<br></font><br>                       newMaterialType1 = gpu-&gt;addShaderMaterialFromFiles(vsFileName,<br>                           psFileName, mc, video::EMT_SOLID);<br><br>                      newMaterialType2 = gpu-&gt;addShaderMaterialFromFiles(vsFileName,<br>                           psFileName, mc, video::EMT_TRANSPARENT_ADD_COLOR);<br>          }<br><br>               mc-&gt;drop();<br>      }<br></pre></td>
 
137
          </tr>
 
138
        </table>
 
139
        <p> Now its time for testing out the materials. We create a test cube 
 
140
          and set the material we created. In addition, we add a text scene node 
 
141
          to the cube and a rotatation animator, to make it look more interesting 
 
142
          and important. </p>
 
143
        <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
144
          <tr> 
 
145
            <td><pre><font color="#006600">
 
146
        // create test scene node 1, with the new created material type 1</font>
 
147
 
 
148
        scene::ISceneNode* node = smgr-&gt;addCubeSceneNode(50);
 
149
        node-&gt;setPosition(core::vector3df(0,0,0));
 
150
        node-&gt;setMaterialTexture(0, driver-&gt;getTexture(&quot;../../media/wall.bmp&quot;));
 
151
        node-&gt;setMaterialFlag(video::EMF_LIGHTING, false);
 
152
        node-&gt;setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1);
 
153
 
 
154
        smgr-&gt;addTextSceneNode(gui-&gt;getBuiltInFont(),
 
155
                        L&quot;PS &amp; VS &amp; EMT_SOLID&quot;,
 
156
                        video::SColor(255,255,255,255), node);
 
157
 
 
158
        scene::ISceneNodeAnimator* anim = smgr-&gt;createRotationAnimator(
 
159
                        core::vector3df(0,0.3f,0));
 
160
        node-&gt;addAnimator(anim);
 
161
        anim-&gt;drop();</pre></td>
 
162
          </tr>
 
163
        </table>
 
164
        <p> Same for the second cube, but with the second material we created.</p>
 
165
        <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
166
          <tr> 
 
167
            <td><pre>   <font color="#006600">// create test scene node 2, with the new created material type 2</font>
 
168
 
 
169
        node = smgr-&gt;addCubeSceneNode(50);
 
170
        node-&gt;setPosition(core::vector3df(0,-10,50));
 
171
        node-&gt;setMaterialTexture(0, driver-&gt;getTexture(&quot;../../media/wall.bmp&quot;));
 
172
        node-&gt;setMaterialFlag(video::EMF_LIGHTING, false);
 
173
        node-&gt;setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2);
 
174
 
 
175
        smgr-&gt;addTextSceneNode(gui-&gt;getBuiltInFont(),
 
176
                        L&quot;PS &amp; VS &amp; EMT_TRANSPARENT&quot;,
 
177
                        video::SColor(255,255,255,255), node);
 
178
 
 
179
        anim = smgr-&gt;createRotationAnimator(core::vector3df(0,0.3f,0));
 
180
        node-&gt;addAnimator(anim);
 
181
        anim-&gt;drop();</pre></td>
 
182
          </tr>
 
183
        </table>
 
184
        <br>
 
185
        Then we add a third cube without a shader on it, to be able to compare 
 
186
        the cubes.<br>
 
187
        <br>
 
188
        <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
189
          <tr> 
 
190
            <td><pre>   <font color="#006600">// add a scene node with no shader </font>
 
191
 
 
192
        node = smgr-&gt;addCubeSceneNode(50);
 
193
        node-&gt;setPosition(core::vector3df(0,50,25));
 
194
        node-&gt;setMaterialTexture(0, driver-&gt;getTexture(&quot;../../media/wall.bmp&quot;));
 
195
        node-&gt;setMaterialFlag(video::EMF_LIGHTING, false);
 
196
        smgr-&gt;addTextSceneNode(gui-&gt;getBuiltInFont(), L&quot;NO SHADER&quot;,
 
197
                video::SColor(255,255,255,255), node);
 
198
            </pre></td>
 
199
          </tr>
 
200
        </table>
 
201
        <br>
 
202
        And last, we add a skybox and a user controlled camera to the scene. For 
 
203
        the skybox textures, we disable mipmap generation, because we don't need 
 
204
        mipmaps on it.<br>
 
205
        <br>
 
206
        <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
207
          <tr> 
 
208
            <td><pre>   <font color="#006600">// add a nice skybox</font><br><br>       driver-&gt;setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);<br><br>  smgr-&gt;addSkyBoxSceneNode(<br>                driver-&gt;getTexture(&quot;../../media/irrlicht2_up.jpg&quot;),<br>            driver-&gt;getTexture(&quot;../../media/irrlicht2_dn.jpg&quot;),<br>            driver-&gt;getTexture(&quot;../../media/irrlicht2_lf.jpg&quot;),<br>            driver-&gt;getTexture(&quot;../../media/irrlicht2_rt.jpg&quot;),<br>            driver-&gt;getTexture(&quot;../../media/irrlicht2_ft.jpg&quot;),<br>            driver-&gt;getTexture(&quot;../../media/irrlicht2_bk.jpg&quot;));<br><br>       driver-&gt;setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);<br><br><font color="#006600">     // add a camera and disable the mouse curso</font>r<br><br>     scene::ICameraSceneNode* cam = smgr-&gt;addCameraSceneNodeFPS(0, 100.0f, 100.0f);<br>   cam-&gt;setPosition(core::vector3df(-100,50,100));<br>  cam-&gt;setTarget(core::vector3df(0,0,0));<br>  device-&gt;getCursorControl()-&gt;setVisible(false);</pre></td>
 
209
          </tr>
 
210
        </table>
 
211
        <br>
 
212
        Now draw everything. That's all.<br>
 
213
        <br>
 
214
        <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
215
          <tr> 
 
216
            <td><pre>   int lastFPS = -1;<br><br>       while(device-&gt;run())<br>             if (device-&gt;isWindowActive())<br>    {<br>           driver-&gt;beginScene(true, true, video::SColor(255,0,0,0));<br>                smgr-&gt;drawAll();<br>         driver-&gt;endScene();<br><br>          int fps = driver-&gt;getFPS();<br><br>          if (lastFPS != fps)<br>         {<br>             core::stringw str = L&quot;Irrlicht Engine - Vertex and pixel shader example [&quot;;<br>               str += driver-&gt;getName();<br>                str += &quot;] FPS:&quot;;<br>                  str += fps;<br>                 device-&gt;setWindowCaption(str.c_str());<br>           lastFPS = fps;<br>            }<br>   }<br><br>       device-&gt;drop();<br>  <br>    return 0;<br></pre></td>
 
217
          </tr>
 
218
        </table>
 
219
        <br>
 
220
        Compile and run this, and I hope you have fun with your new little shader 
 
221
        writing tool :).<br>
 
222
      </div>
 
223
      </td>
 
224
  </tr>
 
225
</table>
 
226
<br>
 
227
<table width="95%" border="0" cellspacing="0" cellpadding="2" align="center">
 
228
  <tr> 
 
229
    <td bgcolor="#666699"> <b><font color="#FFFFFF">Shader files</font></b></td>
 
230
  </tr>
 
231
  <tr> 
 
232
    <td height="90" bgcolor="#eeeeff" valign="top"> <div align="left"> 
 
233
        <div align="left"> 
 
234
          <p>The files containing the shaders can be found in the media directory 
 
235
            of the SDK. However, they look like this:</p>
 
236
          <table width="95%" border="0" cellspacing="4" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
237
            <tr> 
 
238
              <td><strong>D3D9.HLSL</strong></td>
 
239
            </tr>
 
240
            <tr> 
 
241
              <td>
 
242
<pre>
 
243
// part of the Irrlicht Engine Shader example.
 
244
// These simple Direct3D9 pixel and vertex shaders will be loaded by the shaders
 
245
// example. Please note that these example shaders don't do anything really useful. 
 
246
// They only demonstrate that shaders can be used in Irrlicht.
 
247
 
 
248
//-----------------------------------------------------------------------------
 
249
// Global variables
 
250
//-----------------------------------------------------------------------------
 
251
float4x4 mWorldViewProj;  // World * View * Projection transformation
 
252
float4x4 mInvWorld;       // Inverted world matrix
 
253
float4x4 mTransWorld;     // Transposed world matrix
 
254
float3 mLightPos;         // Light position
 
255
float4 mLightColor;       // Light color
 
256
 
 
257
 
 
258
// Vertex shader output structure
 
259
struct VS_OUTPUT
 
260
{
 
261
        float4 Position   : POSITION;   // vertex position 
 
262
        float4 Diffuse    : COLOR0;     // vertex diffuse color
 
263
        float2 TexCoord   : TEXCOORD0;  // tex coords
 
264
};
 
265
 
 
266
 
 
267
VS_OUTPUT vertexMain( in float4 vPosition : POSITION,
 
268
                      in float3 vNormal   : NORMAL,
 
269
                      float2 texCoord     : TEXCOORD0 )
 
270
{
 
271
        VS_OUTPUT Output;
 
272
 
 
273
        // transform position to clip space 
 
274
        Output.Position = mul(vPosition, mWorldViewProj);
 
275
        
 
276
        // transform normal 
 
277
        float3 normal = mul(vNormal, mInvWorld);
 
278
        
 
279
        // renormalize normal 
 
280
        normal = normalize(normal);
 
281
        
 
282
        // position in world coodinates
 
283
        float3 worldpos = mul(mTransWorld, vPosition);
 
284
        
 
285
        // calculate light vector, vtxpos - lightpos
 
286
        float3 lightVector = worldpos - mLightPos;
 
287
        
 
288
        // normalize light vector 
 
289
        lightVector = normalize(lightVector);
 
290
        
 
291
        // calculate light color 
 
292
        float3 tmp = dot(-lightVector, normal);
 
293
        tmp = lit(tmp.x, tmp.y, 1.0);
 
294
        
 
295
        tmp = mLightColor * tmp.y;
 
296
        Output.Diffuse = float4(tmp.x, tmp.y, tmp.z, 0);
 
297
        Output.TexCoord = texCoord;
 
298
        
 
299
        return Output;
 
300
}
 
301
 
 
302
 
 
303
 
 
304
// Pixel shader output structure
 
305
struct PS_OUTPUT
 
306
{
 
307
    float4 RGBColor : COLOR0;  // Pixel color    
 
308
};
 
309
 
 
310
 
 
311
sampler2D tex0;
 
312
        
 
313
PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,
 
314
                     float4 Position : POSITION,
 
315
                     float4 Diffuse  : COLOR0 ) 
 
316
 
317
        PS_OUTPUT Output;
 
318
 
 
319
        float4 col = tex2D( tex0, TexCoord );  // sample color map
 
320
        
 
321
        // multiply with diffuse and do other senseless operations
 
322
        Output.RGBColor = Diffuse * col;
 
323
        Output.RGBColor *= 4.0;
 
324
 
 
325
        return Output;
 
326
}</pre></td>
 
327
            </tr>
 
328
          </table>
 
329
          <br>
 
330
          <table width="95%" border="0" cellspacing="4" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
331
            <tr> 
 
332
              <td><strong>D3D9.VSH</strong></td>
 
333
            </tr>
 
334
            <tr> 
 
335
              <td> <pre>
 
336
; part of the Irrlicht Engine Shader example.
 
337
; This Direct3D9 vertex shader will be loaded by the engine.
 
338
; Please note that these example shaders don't do anything really useful. 
 
339
; They only demonstrate that shaders can be used in Irrlicht.<br>
 
340
vs.1.1
 
341
 
 
342
dcl_position v0;    ; declare position
 
343
dcl_normal v1;      ; declare normal
 
344
dcl_color v2;       ; declare color
 
345
dcl_texcoord0 v3;   ; declare texture coordinate<br>
 
346
; transpose and transform position to clip space 
 
347
mul r0, v0.x, c4      
 
348
mad r0, v0.y, c5, r0   
 
349
mad r0, v0.z, c6, r0   
 
350
add oPos, c7, r0       
 
351
 
 
352
; transform normal 
 
353
dp3 r1.x, v1, c0  
 
354
dp3 r1.y, v1, c1  
 
355
dp3 r1.z, v1, c2  
 
356
 
 
357
; renormalize normal 
 
358
dp3 r1.w, r1, r1  
 
359
rsq r1.w, r1.w    
 
360
mul r1, r1, r1.w  
 
361
 
 
362
; calculate light vector 
 
363
m4x4 r6, v0, c10      ; vertex into world position
 
364
add r2, c8, -r6       ; vtxpos - lightpos
 
365
 
 
366
; normalize light vector 
 
367
dp3 r2.w, r2, r2  
 
368
rsq r2.w, r2.w    
 
369
mul r2, r2, r2.w  
 
370
 
 
371
; calculate light color 
 
372
dp3 r3, r1, r2       ; dp3 with negative light vector 
 
373
lit r5, r3           ; clamp to zero if r3 < 0, r5 has diffuce component in r5.y
 
374
mul oD0, r5.y, c9    ; ouput diffuse color 
 
375
mov oT0, v3          ; store texture coordinates     </pre> </td>
 
376
            </tr>
 
377
          </table>
 
378
          <br>
 
379
          <table width="95%" border="0" cellspacing="4" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
380
            <tr> 
 
381
              <td><strong>D3D9.PSH</strong></td>
 
382
            </tr>
 
383
            <tr> 
 
384
              <td> <pre>
 
385
; part of the Irrlicht Engine Shader example.
 
386
; This simple Direct3D9 pixel shader will be loaded by the engine.
 
387
; Please note that these example shaders don't do anything really useful. 
 
388
; They only demonstrate that shaders can be used in Irrlicht.<br>
 
389
ps.1.1
 
390
 
 
391
tex t0          ; sample color map
 
392
add r0, v0, v0  ; mulitply with color
 
393
mul t0, t0, r0  ; mulitply with color
 
394
add r0, t0, t0  ; make it brighter and store result              
 
395
              </pre> </td>
 
396
            </tr>
 
397
          </table>
 
398
          <br>
 
399
          <table width="95%" border="0" cellspacing="4" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
400
            <tr> 
 
401
              <td><strong>D3D8.VSH</strong></td>
 
402
            </tr>
 
403
            <tr> 
 
404
              <td> <pre>
 
405
; part of the Irrlicht Engine Shader example.
 
406
; This Direct3D9 vertex shader will be loaded by the engine.
 
407
; Please note that these example shaders don't do anything really useful. 
 
408
; They only demonstrate that shaders can be used in Irrlicht.<br>
 
409
vs.1.1
 
410
 
 
411
; transpose and transform position to clip space 
 
412
mul r0, v0.x, c4      
 
413
mad r0, v0.y, c5, r0   
 
414
mad r0, v0.z, c6, r0   
 
415
add oPos, c7, r0       
 
416
 
 
417
; transform normal 
 
418
dp3 r1.x, v1, c0  
 
419
dp3 r1.y, v1, c1  
 
420
dp3 r1.z, v1, c2  
 
421
 
 
422
; renormalize normal 
 
423
dp3 r1.w, r1, r1  
 
424
rsq r1.w, r1.w    
 
425
mul r1, r1, r1.w  
 
426
 
 
427
; calculate light vector 
 
428
m4x4 r6, v0, c10      ; vertex into world position
 
429
add r2, c8, -r6       ; vtxpos - lightpos
 
430
 
 
431
; normalize light vector 
 
432
dp3 r2.w, r2, r2  
 
433
rsq r2.w, r2.w    
 
434
mul r2, r2, r2.w  
 
435
 
 
436
; calculate light color 
 
437
dp3 r3, r1, r2       ; dp3 with negative light vector 
 
438
lit r5, r3           ; clamp to zero if r3 < 0, r5 has diffuce component in r5.y
 
439
mul oD0, r5.y, c9    ; ouput diffuse color 
 
440
mov oT0, v3          ; store texture coordinates             </pre> </td>
 
441
            </tr>
 
442
          </table>
 
443
          <br>
 
444
          <table width="95%" border="0" cellspacing="4" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
445
            <tr> 
 
446
              <td><strong>D3D8.PSH</strong></td>
 
447
            </tr>
 
448
            <tr> 
 
449
              <td> <pre>
 
450
; part of the Irrlicht Engine Shader example.
 
451
; This simple Direct3D9 pixel shader will be loaded by the engine.
 
452
; Please note that these example shaders don't do anything really useful. 
 
453
; They only demonstrate that shaders can be used in Irrlicht.<br>
 
454
ps.1.1
 
455
 
 
456
tex t0             ; sample color map
 
457
mul_x2 t0, t0, v0  ; mulitply with color
 
458
add r0, t0, t0     ; make it brighter and store result      </pre> </td>
 
459
            </tr>
 
460
          </table>
 
461
          <br>
 
462
          <table width="95%" border="0" cellspacing="4" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
463
            <tr> 
 
464
              <td><strong>OPENGL.VSH</strong></td>
 
465
            </tr>
 
466
            <tr> 
 
467
              <td> <pre>
 
468
!!ARBvp1.0
 
469
# part of the Irrlicht Engine Shader example.
 
470
# Please note that these example shaders don't do anything really useful. 
 
471
# They only demonstrate that shaders can be used in Irrlicht.<br>
 
472
#input
 
473
ATTRIB InPos = vertex.position;
 
474
ATTRIB InColor = vertex.color;
 
475
ATTRIB InNormal = vertex.normal;
 
476
ATTRIB InTexCoord = vertex.texcoord;
 
477
 
 
478
#output
 
479
OUTPUT OutPos = result.position;
 
480
OUTPUT OutColor = result.color;
 
481
OUTPUT OutTexCoord = result.texcoord;
 
482
 
 
483
PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix.
 
484
TEMP Temp;
 
485
TEMP TempColor;
 
486
TEMP TempNormal;
 
487
TEMP TempPos;
 
488
 
 
489
#transform position to clip space 
 
490
DP4 Temp.x, MVP[0], InPos;
 
491
DP4 Temp.y, MVP[1], InPos;
 
492
DP4 Temp.z, MVP[2], InPos;
 
493
DP4 Temp.w, MVP[3], InPos;
 
494
 
 
495
#transform normal
 
496
DP3 TempNormal.x, InNormal.x, program.local[0];
 
497
DP3 TempNormal.y, InNormal.y, program.local[1]; 
 
498
DP3 TempNormal.z, InNormal.z, program.local[2];
 
499
 
 
500
#renormalize normal
 
501
DP3 TempNormal.w, TempNormal, TempNormal;  
 
502
RSQ TempNormal.w, TempNormal.w;    
 
503
MUL TempNormal, TempNormal, TempNormal.w;
 
504
 
 
505
# calculate light vector 
 
506
DP4 TempPos.x, InPos, program.local[10];   # vertex into world position
 
507
DP4 TempPos.y, InPos, program.local[11];
 
508
DP4 TempPos.z, InPos, program.local[12];
 
509
DP4 TempPos.w, InPos, program.local[13];
 
510
 
 
511
ADD TempPos, program.local[8], -TempPos;    # vtxpos - lightpos
 
512
 
 
513
# normalize light vector
 
514
DP3 TempPos.w, TempPos, TempPos;  
 
515
RSQ TempPos.w, TempPos.w;    
 
516
MUL TempPos, TempPos, TempPos.w;
 
517
 
 
518
# calculate light color
 
519
DP3 TempColor, TempNormal, TempPos;    # dp3 with negative light vector 
 
520
LIT OutColor, TempColor;  # clamp to zero if r3 < 0, r5 has diffuce component in r5.y
 
521
MUL OutColor, TempColor.y, program.local[9]; # ouput diffuse color 
 
522
MOV OutColor.w, 1.0;          # we want alpha to be always 1
 
523
MOV OutTexCoord, InTexCoord; # store texture coordinate
 
524
MOV OutPos, Temp;
 
525
 
 
526
END</pre> </td>
 
527
            </tr>
 
528
          </table>
 
529
          <br>
 
530
          <table width="95%" border="0" cellspacing="4" cellpadding="0" bgcolor="#CCCCCC" align="center">
 
531
            <tr> 
 
532
              <td><strong>OPENGL.PSH</strong></td>
 
533
            </tr>
 
534
            <tr> 
 
535
              <td> <pre>
 
536
!!ARBfp1.0
 
537
# part of the Irrlicht Engine Shader example.
 
538
# Please note that these example shaders don't do anything really useful. 
 
539
# They only demonstrate that shaders can be used in Irrlicht.<br>
 
540
#Input
 
541
ATTRIB inTexCoord = fragment.texcoord;      # texture coordinates
 
542
ATTRIB inColor = fragment.color.primary; # interpolated diffuse color
 
543
 
 
544
#Output
 
545
OUTPUT outColor = result.color;
 
546
 
 
547
TEMP texelColor;
 
548
TEMP tmp;
 
549
TXP texelColor, inTexCoord, texture, 2D; 
 
550
 
 
551
ADD tmp, inColor, inColor; # mulitply with color
 
552
MUL texelColor, texelColor, tmp;  # mulitply with color   
 
553
ADD outColor, texelColor, texelColor;  # make it brighter and store result
 
554
 
 
555
END          </pre> </td>
 
556
            </tr>
 
557
          </table>
 
558
          <p>&nbsp; </p>
 
559
        </div>
 
560
      </div></td>
 
561
  </tr>
 
562
</table>
 
563
<p>&nbsp;</p>
 
564
<p>&nbsp;</p>
 
565
      </body>
 
566
</html>