diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/examples/10.Shaders/main.cpp | 886 |
1 files changed, 443 insertions, 443 deletions
diff --git a/libraries/irrlicht-1.8/examples/10.Shaders/main.cpp b/libraries/irrlicht-1.8/examples/10.Shaders/main.cpp index 269c47f..13a4599 100644 --- a/libraries/irrlicht-1.8/examples/10.Shaders/main.cpp +++ b/libraries/irrlicht-1.8/examples/10.Shaders/main.cpp | |||
@@ -1,443 +1,443 @@ | |||
1 | /** Example 010 Shaders | 1 | /** Example 010 Shaders |
2 | 2 | ||
3 | This tutorial shows how to use shaders for D3D8, D3D9, OpenGL, and Cg with the | 3 | This tutorial shows how to use shaders for D3D8, D3D9, OpenGL, and Cg with the |
4 | engine and how to create new material types with them. It also shows how to | 4 | engine and how to create new material types with them. It also shows how to |
5 | disable the generation of mipmaps at texture loading, and how to use text scene | 5 | disable the generation of mipmaps at texture loading, and how to use text scene |
6 | nodes. | 6 | nodes. |
7 | 7 | ||
8 | This tutorial does not explain how shaders work. I would recommend to read the | 8 | This tutorial does not explain how shaders work. I would recommend to read the |
9 | D3D, OpenGL, or Cg documentation, to search a tutorial, or to read a book about | 9 | D3D, OpenGL, or Cg documentation, to search a tutorial, or to read a book about |
10 | this. | 10 | this. |
11 | 11 | ||
12 | At first, we need to include all headers and do the stuff we always do, like in | 12 | At first, we need to include all headers and do the stuff we always do, like in |
13 | nearly all other tutorials: | 13 | nearly all other tutorials: |
14 | */ | 14 | */ |
15 | #include <irrlicht.h> | 15 | #include <irrlicht.h> |
16 | #include <iostream> | 16 | #include <iostream> |
17 | #include "driverChoice.h" | 17 | #include "driverChoice.h" |
18 | 18 | ||
19 | using namespace irr; | 19 | using namespace irr; |
20 | 20 | ||
21 | #ifdef _MSC_VER | 21 | #ifdef _MSC_VER |
22 | #pragma comment(lib, "Irrlicht.lib") | 22 | #pragma comment(lib, "Irrlicht.lib") |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | /* | 25 | /* |
26 | Because we want to use some interesting shaders in this tutorials, we need to | 26 | Because we want to use some interesting shaders in this tutorials, we need to |
27 | set some data for them to make them able to compute nice colors. In this | 27 | set some data for them to make them able to compute nice colors. In this |
28 | example, we'll use a simple vertex shader which will calculate the color of the | 28 | example, we'll use a simple vertex shader which will calculate the color of the |
29 | vertex based on the position of the camera. | 29 | vertex based on the position of the camera. |
30 | For this, the shader needs the following data: The inverted world matrix for | 30 | For this, the shader needs the following data: The inverted world matrix for |
31 | transforming the normal, the clip matrix for transforming the position, the | 31 | transforming the normal, the clip matrix for transforming the position, the |
32 | camera position and the world position of the object for the calculation of the | 32 | camera position and the world position of the object for the calculation of the |
33 | angle of light, and the color of the light. To be able to tell the shader all | 33 | angle of light, and the color of the light. To be able to tell the shader all |
34 | this data every frame, we have to derive a class from the | 34 | this data every frame, we have to derive a class from the |
35 | IShaderConstantSetCallBack interface and override its only method, namely | 35 | IShaderConstantSetCallBack interface and override its only method, namely |
36 | OnSetConstants(). This method will be called every time the material is set. | 36 | OnSetConstants(). This method will be called every time the material is set. |
37 | The method setVertexShaderConstant() of the IMaterialRendererServices interface | 37 | The method setVertexShaderConstant() of the IMaterialRendererServices interface |
38 | is used to set the data the shader needs. If the user chose to use a High Level | 38 | is used to set the data the shader needs. If the user chose to use a High Level |
39 | shader language like HLSL instead of Assembler in this example, you have to set | 39 | shader language like HLSL instead of Assembler in this example, you have to set |
40 | the variable name as parameter instead of the register index. | 40 | the variable name as parameter instead of the register index. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | IrrlichtDevice* device = 0; | 43 | IrrlichtDevice* device = 0; |
44 | bool UseHighLevelShaders = false; | 44 | bool UseHighLevelShaders = false; |
45 | bool UseCgShaders = false; | 45 | bool UseCgShaders = false; |
46 | 46 | ||
47 | class MyShaderCallBack : public video::IShaderConstantSetCallBack | 47 | class MyShaderCallBack : public video::IShaderConstantSetCallBack |
48 | { | 48 | { |
49 | public: | 49 | public: |
50 | 50 | ||
51 | virtual void OnSetConstants(video::IMaterialRendererServices* services, | 51 | virtual void OnSetConstants(video::IMaterialRendererServices* services, |
52 | s32 userData) | 52 | s32 userData) |
53 | { | 53 | { |
54 | video::IVideoDriver* driver = services->getVideoDriver(); | 54 | video::IVideoDriver* driver = services->getVideoDriver(); |
55 | 55 | ||
56 | // set inverted world matrix | 56 | // set inverted world matrix |
57 | // if we are using highlevel shaders (the user can select this when | 57 | // if we are using highlevel shaders (the user can select this when |
58 | // starting the program), we must set the constants by name. | 58 | // starting the program), we must set the constants by name. |
59 | 59 | ||
60 | core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD); | 60 | core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD); |
61 | invWorld.makeInverse(); | 61 | invWorld.makeInverse(); |
62 | 62 | ||
63 | if (UseHighLevelShaders) | 63 | if (UseHighLevelShaders) |
64 | services->setVertexShaderConstant("mInvWorld", invWorld.pointer(), 16); | 64 | services->setVertexShaderConstant("mInvWorld", invWorld.pointer(), 16); |
65 | else | 65 | else |
66 | services->setVertexShaderConstant(invWorld.pointer(), 0, 4); | 66 | services->setVertexShaderConstant(invWorld.pointer(), 0, 4); |
67 | 67 | ||
68 | // set clip matrix | 68 | // set clip matrix |
69 | 69 | ||
70 | core::matrix4 worldViewProj; | 70 | core::matrix4 worldViewProj; |
71 | worldViewProj = driver->getTransform(video::ETS_PROJECTION); | 71 | worldViewProj = driver->getTransform(video::ETS_PROJECTION); |
72 | worldViewProj *= driver->getTransform(video::ETS_VIEW); | 72 | worldViewProj *= driver->getTransform(video::ETS_VIEW); |
73 | worldViewProj *= driver->getTransform(video::ETS_WORLD); | 73 | worldViewProj *= driver->getTransform(video::ETS_WORLD); |
74 | 74 | ||
75 | if (UseHighLevelShaders) | 75 | if (UseHighLevelShaders) |
76 | services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16); | 76 | services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16); |
77 | else | 77 | else |
78 | services->setVertexShaderConstant(worldViewProj.pointer(), 4, 4); | 78 | services->setVertexShaderConstant(worldViewProj.pointer(), 4, 4); |
79 | 79 | ||
80 | // set camera position | 80 | // set camera position |
81 | 81 | ||
82 | core::vector3df pos = device->getSceneManager()-> | 82 | core::vector3df pos = device->getSceneManager()-> |
83 | getActiveCamera()->getAbsolutePosition(); | 83 | getActiveCamera()->getAbsolutePosition(); |
84 | 84 | ||
85 | if (UseHighLevelShaders) | 85 | if (UseHighLevelShaders) |
86 | services->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&pos), 3); | 86 | services->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&pos), 3); |
87 | else | 87 | else |
88 | services->setVertexShaderConstant(reinterpret_cast<f32*>(&pos), 8, 1); | 88 | services->setVertexShaderConstant(reinterpret_cast<f32*>(&pos), 8, 1); |
89 | 89 | ||
90 | // set light color | 90 | // set light color |
91 | 91 | ||
92 | video::SColorf col(0.0f,1.0f,1.0f,0.0f); | 92 | video::SColorf col(0.0f,1.0f,1.0f,0.0f); |
93 | 93 | ||
94 | if (UseHighLevelShaders) | 94 | if (UseHighLevelShaders) |
95 | services->setVertexShaderConstant("mLightColor", | 95 | services->setVertexShaderConstant("mLightColor", |
96 | reinterpret_cast<f32*>(&col), 4); | 96 | reinterpret_cast<f32*>(&col), 4); |
97 | else | 97 | else |
98 | services->setVertexShaderConstant(reinterpret_cast<f32*>(&col), 9, 1); | 98 | services->setVertexShaderConstant(reinterpret_cast<f32*>(&col), 9, 1); |
99 | 99 | ||
100 | // set transposed world matrix | 100 | // set transposed world matrix |
101 | 101 | ||
102 | core::matrix4 world = driver->getTransform(video::ETS_WORLD); | 102 | core::matrix4 world = driver->getTransform(video::ETS_WORLD); |
103 | world = world.getTransposed(); | 103 | world = world.getTransposed(); |
104 | 104 | ||
105 | if (UseHighLevelShaders) | 105 | if (UseHighLevelShaders) |
106 | { | 106 | { |
107 | services->setVertexShaderConstant("mTransWorld", world.pointer(), 16); | 107 | services->setVertexShaderConstant("mTransWorld", world.pointer(), 16); |
108 | 108 | ||
109 | // set texture, for textures you can use both an int and a float setPixelShaderConstant interfaces (You need it only for an OpenGL driver). | 109 | // set texture, for textures you can use both an int and a float setPixelShaderConstant interfaces (You need it only for an OpenGL driver). |
110 | s32 TextureLayerID = 0; | 110 | s32 TextureLayerID = 0; |
111 | if (UseHighLevelShaders) | 111 | if (UseHighLevelShaders) |
112 | services->setPixelShaderConstant("myTexture", &TextureLayerID, 1); | 112 | services->setPixelShaderConstant("myTexture", &TextureLayerID, 1); |
113 | } | 113 | } |
114 | else | 114 | else |
115 | services->setVertexShaderConstant(world.pointer(), 10, 4); | 115 | services->setVertexShaderConstant(world.pointer(), 10, 4); |
116 | } | 116 | } |
117 | }; | 117 | }; |
118 | 118 | ||
119 | /* | 119 | /* |
120 | The next few lines start up the engine just like in most other tutorials | 120 | The next few lines start up the engine just like in most other tutorials |
121 | before. But in addition, we ask the user if he wants to use high level shaders | 121 | before. But in addition, we ask the user if he wants to use high level shaders |
122 | in this example, if he selected a driver which is capable of doing so. | 122 | in this example, if he selected a driver which is capable of doing so. |
123 | */ | 123 | */ |
124 | int main() | 124 | int main() |
125 | { | 125 | { |
126 | // ask user for driver | 126 | // ask user for driver |
127 | video::E_DRIVER_TYPE driverType=driverChoiceConsole(); | 127 | video::E_DRIVER_TYPE driverType=driverChoiceConsole(); |
128 | if (driverType==video::EDT_COUNT) | 128 | if (driverType==video::EDT_COUNT) |
129 | return 1; | 129 | return 1; |
130 | 130 | ||
131 | // ask the user if we should use high level shaders for this example | 131 | // ask the user if we should use high level shaders for this example |
132 | if (driverType == video::EDT_DIRECT3D9 || | 132 | if (driverType == video::EDT_DIRECT3D9 || |
133 | driverType == video::EDT_OPENGL) | 133 | driverType == video::EDT_OPENGL) |
134 | { | 134 | { |
135 | char i; | 135 | char i; |
136 | printf("Please press 'y' if you want to use high level shaders.\n"); | 136 | printf("Please press 'y' if you want to use high level shaders.\n"); |
137 | std::cin >> i; | 137 | std::cin >> i; |
138 | if (i == 'y') | 138 | if (i == 'y') |
139 | { | 139 | { |
140 | UseHighLevelShaders = true; | 140 | UseHighLevelShaders = true; |
141 | printf("Please press 'y' if you want to use Cg shaders.\n"); | 141 | printf("Please press 'y' if you want to use Cg shaders.\n"); |
142 | std::cin >> i; | 142 | std::cin >> i; |
143 | if (i == 'y') | 143 | if (i == 'y') |
144 | UseCgShaders = true; | 144 | UseCgShaders = true; |
145 | } | 145 | } |
146 | } | 146 | } |
147 | 147 | ||
148 | // create device | 148 | // create device |
149 | device = createDevice(driverType, core::dimension2d<u32>(640, 480)); | 149 | device = createDevice(driverType, core::dimension2d<u32>(640, 480)); |
150 | 150 | ||
151 | if (device == 0) | 151 | if (device == 0) |
152 | return 1; // could not create selected driver. | 152 | return 1; // could not create selected driver. |
153 | 153 | ||
154 | video::IVideoDriver* driver = device->getVideoDriver(); | 154 | video::IVideoDriver* driver = device->getVideoDriver(); |
155 | scene::ISceneManager* smgr = device->getSceneManager(); | 155 | scene::ISceneManager* smgr = device->getSceneManager(); |
156 | gui::IGUIEnvironment* gui = device->getGUIEnvironment(); | 156 | gui::IGUIEnvironment* gui = device->getGUIEnvironment(); |
157 | 157 | ||
158 | // Make sure we don't try Cg without support for it | 158 | // Make sure we don't try Cg without support for it |
159 | if (UseCgShaders && !driver->queryFeature(video::EVDF_CG)) | 159 | if (UseCgShaders && !driver->queryFeature(video::EVDF_CG)) |
160 | { | 160 | { |
161 | printf("Warning: No Cg support, disabling.\n"); | 161 | printf("Warning: No Cg support, disabling.\n"); |
162 | UseCgShaders=false; | 162 | UseCgShaders=false; |
163 | } | 163 | } |
164 | 164 | ||
165 | /* | 165 | /* |
166 | Now for the more interesting parts. If we are using Direct3D, we want | 166 | Now for the more interesting parts. If we are using Direct3D, we want |
167 | to load vertex and pixel shader programs, if we have OpenGL, we want to | 167 | to load vertex and pixel shader programs, if we have OpenGL, we want to |
168 | use ARB fragment and vertex programs. I wrote the corresponding | 168 | use ARB fragment and vertex programs. I wrote the corresponding |
169 | programs down into the files d3d8.ps, d3d8.vs, d3d9.ps, d3d9.vs, | 169 | programs down into the files d3d8.ps, d3d8.vs, d3d9.ps, d3d9.vs, |
170 | opengl.ps and opengl.vs. We only need the right filenames now. This is | 170 | opengl.ps and opengl.vs. We only need the right filenames now. This is |
171 | done in the following switch. Note, that it is not necessary to write | 171 | done in the following switch. Note, that it is not necessary to write |
172 | the shaders into text files, like in this example. You can even write | 172 | the shaders into text files, like in this example. You can even write |
173 | the shaders directly as strings into the cpp source file, and use later | 173 | the shaders directly as strings into the cpp source file, and use later |
174 | addShaderMaterial() instead of addShaderMaterialFromFiles(). | 174 | addShaderMaterial() instead of addShaderMaterialFromFiles(). |
175 | */ | 175 | */ |
176 | 176 | ||
177 | io::path vsFileName; // filename for the vertex shader | 177 | io::path vsFileName; // filename for the vertex shader |
178 | io::path psFileName; // filename for the pixel shader | 178 | io::path psFileName; // filename for the pixel shader |
179 | 179 | ||
180 | switch(driverType) | 180 | switch(driverType) |
181 | { | 181 | { |
182 | case video::EDT_DIRECT3D8: | 182 | case video::EDT_DIRECT3D8: |
183 | psFileName = "../../media/d3d8.psh"; | 183 | psFileName = "../../media/d3d8.psh"; |
184 | vsFileName = "../../media/d3d8.vsh"; | 184 | vsFileName = "../../media/d3d8.vsh"; |
185 | break; | 185 | break; |
186 | case video::EDT_DIRECT3D9: | 186 | case video::EDT_DIRECT3D9: |
187 | if (UseHighLevelShaders) | 187 | if (UseHighLevelShaders) |
188 | { | 188 | { |
189 | // Cg can also handle this syntax | 189 | // Cg can also handle this syntax |
190 | psFileName = "../../media/d3d9.hlsl"; | 190 | psFileName = "../../media/d3d9.hlsl"; |
191 | vsFileName = psFileName; // both shaders are in the same file | 191 | vsFileName = psFileName; // both shaders are in the same file |
192 | } | 192 | } |
193 | else | 193 | else |
194 | { | 194 | { |
195 | psFileName = "../../media/d3d9.psh"; | 195 | psFileName = "../../media/d3d9.psh"; |
196 | vsFileName = "../../media/d3d9.vsh"; | 196 | vsFileName = "../../media/d3d9.vsh"; |
197 | } | 197 | } |
198 | break; | 198 | break; |
199 | 199 | ||
200 | case video::EDT_OPENGL: | 200 | case video::EDT_OPENGL: |
201 | if (UseHighLevelShaders) | 201 | if (UseHighLevelShaders) |
202 | { | 202 | { |
203 | if (!UseCgShaders) | 203 | if (!UseCgShaders) |
204 | { | 204 | { |
205 | psFileName = "../../media/opengl.frag"; | 205 | psFileName = "../../media/opengl.frag"; |
206 | vsFileName = "../../media/opengl.vert"; | 206 | vsFileName = "../../media/opengl.vert"; |
207 | } | 207 | } |
208 | else | 208 | else |
209 | { | 209 | { |
210 | // Use HLSL syntax for Cg | 210 | // Use HLSL syntax for Cg |
211 | psFileName = "../../media/d3d9.hlsl"; | 211 | psFileName = "../../media/d3d9.hlsl"; |
212 | vsFileName = psFileName; // both shaders are in the same file | 212 | vsFileName = psFileName; // both shaders are in the same file |
213 | } | 213 | } |
214 | } | 214 | } |
215 | else | 215 | else |
216 | { | 216 | { |
217 | psFileName = "../../media/opengl.psh"; | 217 | psFileName = "../../media/opengl.psh"; |
218 | vsFileName = "../../media/opengl.vsh"; | 218 | vsFileName = "../../media/opengl.vsh"; |
219 | } | 219 | } |
220 | break; | 220 | break; |
221 | } | 221 | } |
222 | 222 | ||
223 | /* | 223 | /* |
224 | In addition, we check if the hardware and the selected renderer is | 224 | In addition, we check if the hardware and the selected renderer is |
225 | capable of executing the shaders we want. If not, we simply set the | 225 | capable of executing the shaders we want. If not, we simply set the |
226 | filename string to 0. This is not necessary, but useful in this | 226 | filename string to 0. This is not necessary, but useful in this |
227 | example: For example, if the hardware is able to execute vertex shaders | 227 | example: For example, if the hardware is able to execute vertex shaders |
228 | but not pixel shaders, we create a new material which only uses the | 228 | but not pixel shaders, we create a new material which only uses the |
229 | vertex shader, and no pixel shader. Otherwise, if we would tell the | 229 | vertex shader, and no pixel shader. Otherwise, if we would tell the |
230 | engine to create this material and the engine sees that the hardware | 230 | engine to create this material and the engine sees that the hardware |
231 | wouldn't be able to fulfill the request completely, it would not | 231 | wouldn't be able to fulfill the request completely, it would not |
232 | create any new material at all. So in this example you would see at | 232 | create any new material at all. So in this example you would see at |
233 | least the vertex shader in action, without the pixel shader. | 233 | least the vertex shader in action, without the pixel shader. |
234 | */ | 234 | */ |
235 | 235 | ||
236 | if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && | 236 | if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && |
237 | !driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1)) | 237 | !driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1)) |
238 | { | 238 | { |
239 | device->getLogger()->log("WARNING: Pixel shaders disabled "\ | 239 | device->getLogger()->log("WARNING: Pixel shaders disabled "\ |
240 | "because of missing driver/hardware support."); | 240 | "because of missing driver/hardware support."); |
241 | psFileName = ""; | 241 | psFileName = ""; |
242 | } | 242 | } |
243 | 243 | ||
244 | if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) && | 244 | if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) && |
245 | !driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) | 245 | !driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) |
246 | { | 246 | { |
247 | device->getLogger()->log("WARNING: Vertex shaders disabled "\ | 247 | device->getLogger()->log("WARNING: Vertex shaders disabled "\ |
248 | "because of missing driver/hardware support."); | 248 | "because of missing driver/hardware support."); |
249 | vsFileName = ""; | 249 | vsFileName = ""; |
250 | } | 250 | } |
251 | 251 | ||
252 | /* | 252 | /* |
253 | Now lets create the new materials. As you maybe know from previous | 253 | Now lets create the new materials. As you maybe know from previous |
254 | examples, a material type in the Irrlicht engine is set by simply | 254 | examples, a material type in the Irrlicht engine is set by simply |
255 | changing the MaterialType value in the SMaterial struct. And this value | 255 | changing the MaterialType value in the SMaterial struct. And this value |
256 | is just a simple 32 bit value, like video::EMT_SOLID. So we only need | 256 | is just a simple 32 bit value, like video::EMT_SOLID. So we only need |
257 | the engine to create a new value for us which we can set there. To do | 257 | the engine to create a new value for us which we can set there. To do |
258 | this, we get a pointer to the IGPUProgrammingServices and call | 258 | this, we get a pointer to the IGPUProgrammingServices and call |
259 | addShaderMaterialFromFiles(), which returns such a new 32 bit value. | 259 | addShaderMaterialFromFiles(), which returns such a new 32 bit value. |
260 | That's all. | 260 | That's all. |
261 | 261 | ||
262 | The parameters to this method are the following: First, the names of | 262 | The parameters to this method are the following: First, the names of |
263 | the files containing the code of the vertex and the pixel shader. If | 263 | the files containing the code of the vertex and the pixel shader. If |
264 | you would use addShaderMaterial() instead, you would not need file | 264 | you would use addShaderMaterial() instead, you would not need file |
265 | names, then you could write the code of the shader directly as string. | 265 | names, then you could write the code of the shader directly as string. |
266 | The following parameter is a pointer to the IShaderConstantSetCallBack | 266 | The following parameter is a pointer to the IShaderConstantSetCallBack |
267 | class we wrote at the beginning of this tutorial. If you don't want to | 267 | class we wrote at the beginning of this tutorial. If you don't want to |
268 | set constants, set this to 0. The last parameter tells the engine which | 268 | set constants, set this to 0. The last parameter tells the engine which |
269 | material it should use as base material. | 269 | material it should use as base material. |
270 | 270 | ||
271 | To demonstrate this, we create two materials with a different base | 271 | To demonstrate this, we create two materials with a different base |
272 | material, one with EMT_SOLID and one with EMT_TRANSPARENT_ADD_COLOR. | 272 | material, one with EMT_SOLID and one with EMT_TRANSPARENT_ADD_COLOR. |
273 | */ | 273 | */ |
274 | 274 | ||
275 | // create materials | 275 | // create materials |
276 | 276 | ||
277 | video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices(); | 277 | video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices(); |
278 | s32 newMaterialType1 = 0; | 278 | s32 newMaterialType1 = 0; |
279 | s32 newMaterialType2 = 0; | 279 | s32 newMaterialType2 = 0; |
280 | 280 | ||
281 | if (gpu) | 281 | if (gpu) |
282 | { | 282 | { |
283 | MyShaderCallBack* mc = new MyShaderCallBack(); | 283 | MyShaderCallBack* mc = new MyShaderCallBack(); |
284 | 284 | ||
285 | // create the shaders depending on if the user wanted high level | 285 | // create the shaders depending on if the user wanted high level |
286 | // or low level shaders: | 286 | // or low level shaders: |
287 | 287 | ||
288 | if (UseHighLevelShaders) | 288 | if (UseHighLevelShaders) |
289 | { | 289 | { |
290 | // Choose the desired shader type. Default is the native | 290 | // Choose the desired shader type. Default is the native |
291 | // shader type for the driver, for Cg pass the special | 291 | // shader type for the driver, for Cg pass the special |
292 | // enum value EGSL_CG | 292 | // enum value EGSL_CG |
293 | const video::E_GPU_SHADING_LANGUAGE shadingLanguage = | 293 | const video::E_GPU_SHADING_LANGUAGE shadingLanguage = |
294 | UseCgShaders ? video::EGSL_CG:video::EGSL_DEFAULT; | 294 | UseCgShaders ? video::EGSL_CG:video::EGSL_DEFAULT; |
295 | 295 | ||
296 | // create material from high level shaders (hlsl, glsl or cg) | 296 | // create material from high level shaders (hlsl, glsl or cg) |
297 | 297 | ||
298 | newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles( | 298 | newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles( |
299 | vsFileName, "vertexMain", video::EVST_VS_1_1, | 299 | vsFileName, "vertexMain", video::EVST_VS_1_1, |
300 | psFileName, "pixelMain", video::EPST_PS_1_1, | 300 | psFileName, "pixelMain", video::EPST_PS_1_1, |
301 | mc, video::EMT_SOLID, 0, shadingLanguage); | 301 | mc, video::EMT_SOLID, 0, shadingLanguage); |
302 | 302 | ||
303 | newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles( | 303 | newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles( |
304 | vsFileName, "vertexMain", video::EVST_VS_1_1, | 304 | vsFileName, "vertexMain", video::EVST_VS_1_1, |
305 | psFileName, "pixelMain", video::EPST_PS_1_1, | 305 | psFileName, "pixelMain", video::EPST_PS_1_1, |
306 | mc, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage); | 306 | mc, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage); |
307 | } | 307 | } |
308 | else | 308 | else |
309 | { | 309 | { |
310 | // create material from low level shaders (asm or arb_asm) | 310 | // create material from low level shaders (asm or arb_asm) |
311 | 311 | ||
312 | newMaterialType1 = gpu->addShaderMaterialFromFiles(vsFileName, | 312 | newMaterialType1 = gpu->addShaderMaterialFromFiles(vsFileName, |
313 | psFileName, mc, video::EMT_SOLID); | 313 | psFileName, mc, video::EMT_SOLID); |
314 | 314 | ||
315 | newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName, | 315 | newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName, |
316 | psFileName, mc, video::EMT_TRANSPARENT_ADD_COLOR); | 316 | psFileName, mc, video::EMT_TRANSPARENT_ADD_COLOR); |
317 | } | 317 | } |
318 | 318 | ||
319 | mc->drop(); | 319 | mc->drop(); |
320 | } | 320 | } |
321 | 321 | ||
322 | /* | 322 | /* |
323 | Now it's time for testing the materials. We create a test cube and set | 323 | Now it's time for testing the materials. We create a test cube and set |
324 | the material we created. In addition, we add a text scene node to the | 324 | the material we created. In addition, we add a text scene node to the |
325 | cube and a rotation animator to make it look more interesting and | 325 | cube and a rotation animator to make it look more interesting and |
326 | important. | 326 | important. |
327 | */ | 327 | */ |
328 | 328 | ||
329 | // create test scene node 1, with the new created material type 1 | 329 | // create test scene node 1, with the new created material type 1 |
330 | 330 | ||
331 | scene::ISceneNode* node = smgr->addCubeSceneNode(50); | 331 | scene::ISceneNode* node = smgr->addCubeSceneNode(50); |
332 | node->setPosition(core::vector3df(0,0,0)); | 332 | node->setPosition(core::vector3df(0,0,0)); |
333 | node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp")); | 333 | node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp")); |
334 | node->setMaterialFlag(video::EMF_LIGHTING, false); | 334 | node->setMaterialFlag(video::EMF_LIGHTING, false); |
335 | node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1); | 335 | node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1); |
336 | 336 | ||
337 | smgr->addTextSceneNode(gui->getBuiltInFont(), | 337 | smgr->addTextSceneNode(gui->getBuiltInFont(), |
338 | L"PS & VS & EMT_SOLID", | 338 | L"PS & VS & EMT_SOLID", |
339 | video::SColor(255,255,255,255), node); | 339 | video::SColor(255,255,255,255), node); |
340 | 340 | ||
341 | scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator( | 341 | scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator( |
342 | core::vector3df(0,0.3f,0)); | 342 | core::vector3df(0,0.3f,0)); |
343 | node->addAnimator(anim); | 343 | node->addAnimator(anim); |
344 | anim->drop(); | 344 | anim->drop(); |
345 | 345 | ||
346 | /* | 346 | /* |
347 | Same for the second cube, but with the second material we created. | 347 | Same for the second cube, but with the second material we created. |
348 | */ | 348 | */ |
349 | 349 | ||
350 | // create test scene node 2, with the new created material type 2 | 350 | // create test scene node 2, with the new created material type 2 |
351 | 351 | ||
352 | node = smgr->addCubeSceneNode(50); | 352 | node = smgr->addCubeSceneNode(50); |
353 | node->setPosition(core::vector3df(0,-10,50)); | 353 | node->setPosition(core::vector3df(0,-10,50)); |
354 | node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp")); | 354 | node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp")); |
355 | node->setMaterialFlag(video::EMF_LIGHTING, false); | 355 | node->setMaterialFlag(video::EMF_LIGHTING, false); |
356 | node->setMaterialFlag(video::EMF_BLEND_OPERATION, true); | 356 | node->setMaterialFlag(video::EMF_BLEND_OPERATION, true); |
357 | node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2); | 357 | node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2); |
358 | 358 | ||
359 | smgr->addTextSceneNode(gui->getBuiltInFont(), | 359 | smgr->addTextSceneNode(gui->getBuiltInFont(), |
360 | L"PS & VS & EMT_TRANSPARENT", | 360 | L"PS & VS & EMT_TRANSPARENT", |
361 | video::SColor(255,255,255,255), node); | 361 | video::SColor(255,255,255,255), node); |
362 | 362 | ||
363 | anim = smgr->createRotationAnimator(core::vector3df(0,0.3f,0)); | 363 | anim = smgr->createRotationAnimator(core::vector3df(0,0.3f,0)); |
364 | node->addAnimator(anim); | 364 | node->addAnimator(anim); |
365 | anim->drop(); | 365 | anim->drop(); |
366 | 366 | ||
367 | /* | 367 | /* |
368 | Then we add a third cube without a shader on it, to be able to compare | 368 | Then we add a third cube without a shader on it, to be able to compare |
369 | the cubes. | 369 | the cubes. |
370 | */ | 370 | */ |
371 | 371 | ||
372 | // add a scene node with no shader | 372 | // add a scene node with no shader |
373 | 373 | ||
374 | node = smgr->addCubeSceneNode(50); | 374 | node = smgr->addCubeSceneNode(50); |
375 | node->setPosition(core::vector3df(0,50,25)); | 375 | node->setPosition(core::vector3df(0,50,25)); |
376 | node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp")); | 376 | node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp")); |
377 | node->setMaterialFlag(video::EMF_LIGHTING, false); | 377 | node->setMaterialFlag(video::EMF_LIGHTING, false); |
378 | smgr->addTextSceneNode(gui->getBuiltInFont(), L"NO SHADER", | 378 | smgr->addTextSceneNode(gui->getBuiltInFont(), L"NO SHADER", |
379 | video::SColor(255,255,255,255), node); | 379 | video::SColor(255,255,255,255), node); |
380 | 380 | ||
381 | /* | 381 | /* |
382 | And last, we add a skybox and a user controlled camera to the scene. | 382 | And last, we add a skybox and a user controlled camera to the scene. |
383 | For the skybox textures, we disable mipmap generation, because we don't | 383 | For the skybox textures, we disable mipmap generation, because we don't |
384 | need mipmaps on it. | 384 | need mipmaps on it. |
385 | */ | 385 | */ |
386 | 386 | ||
387 | // add a nice skybox | 387 | // add a nice skybox |
388 | 388 | ||
389 | driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); | 389 | driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); |
390 | 390 | ||
391 | smgr->addSkyBoxSceneNode( | 391 | smgr->addSkyBoxSceneNode( |
392 | driver->getTexture("../../media/irrlicht2_up.jpg"), | 392 | driver->getTexture("../../media/irrlicht2_up.jpg"), |
393 | driver->getTexture("../../media/irrlicht2_dn.jpg"), | 393 | driver->getTexture("../../media/irrlicht2_dn.jpg"), |
394 | driver->getTexture("../../media/irrlicht2_lf.jpg"), | 394 | driver->getTexture("../../media/irrlicht2_lf.jpg"), |
395 | driver->getTexture("../../media/irrlicht2_rt.jpg"), | 395 | driver->getTexture("../../media/irrlicht2_rt.jpg"), |
396 | driver->getTexture("../../media/irrlicht2_ft.jpg"), | 396 | driver->getTexture("../../media/irrlicht2_ft.jpg"), |
397 | driver->getTexture("../../media/irrlicht2_bk.jpg")); | 397 | driver->getTexture("../../media/irrlicht2_bk.jpg")); |
398 | 398 | ||
399 | driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true); | 399 | driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true); |
400 | 400 | ||
401 | // add a camera and disable the mouse cursor | 401 | // add a camera and disable the mouse cursor |
402 | 402 | ||
403 | scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(); | 403 | scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(); |
404 | cam->setPosition(core::vector3df(-100,50,100)); | 404 | cam->setPosition(core::vector3df(-100,50,100)); |
405 | cam->setTarget(core::vector3df(0,0,0)); | 405 | cam->setTarget(core::vector3df(0,0,0)); |
406 | device->getCursorControl()->setVisible(false); | 406 | device->getCursorControl()->setVisible(false); |
407 | 407 | ||
408 | /* | 408 | /* |
409 | Now draw everything. That's all. | 409 | Now draw everything. That's all. |
410 | */ | 410 | */ |
411 | 411 | ||
412 | int lastFPS = -1; | 412 | int lastFPS = -1; |
413 | 413 | ||
414 | while(device->run()) | 414 | while(device->run()) |
415 | if (device->isWindowActive()) | 415 | if (device->isWindowActive()) |
416 | { | 416 | { |
417 | driver->beginScene(true, true, video::SColor(255,0,0,0)); | 417 | driver->beginScene(true, true, video::SColor(255,0,0,0)); |
418 | smgr->drawAll(); | 418 | smgr->drawAll(); |
419 | driver->endScene(); | 419 | driver->endScene(); |
420 | 420 | ||
421 | int fps = driver->getFPS(); | 421 | int fps = driver->getFPS(); |
422 | 422 | ||
423 | if (lastFPS != fps) | 423 | if (lastFPS != fps) |
424 | { | 424 | { |
425 | core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example ["; | 425 | core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example ["; |
426 | str += driver->getName(); | 426 | str += driver->getName(); |
427 | str += "] FPS:"; | 427 | str += "] FPS:"; |
428 | str += fps; | 428 | str += fps; |
429 | 429 | ||
430 | device->setWindowCaption(str.c_str()); | 430 | device->setWindowCaption(str.c_str()); |
431 | lastFPS = fps; | 431 | lastFPS = fps; |
432 | } | 432 | } |
433 | } | 433 | } |
434 | 434 | ||
435 | device->drop(); | 435 | device->drop(); |
436 | 436 | ||
437 | return 0; | 437 | return 0; |
438 | } | 438 | } |
439 | 439 | ||
440 | /* | 440 | /* |
441 | Compile and run this, and I hope you have fun with your new little shader | 441 | Compile and run this, and I hope you have fun with your new little shader |
442 | writing tool :). | 442 | writing tool :). |
443 | **/ | 443 | **/ |