1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4
5 #ifndef __C_D3D9_MATERIAL_RENDERER_H_INCLUDED__
6 #define __C_D3D9_MATERIAL_RENDERER_H_INCLUDED__
7
8 #include "IrrCompileConfig.h"
9 #ifdef _IRR_WINDOWS_
10
11 #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
12 #if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
13 #include "irrMath.h" // needed by borland for sqrtf define
14 #endif
15 #include <d3d9.h>
16
17 #include "IMaterialRenderer.h"
18
19 namespace irr
20 {
21 namespace video
22 {
23
24 namespace
25 {
26 D3DMATRIX UnitMatrixD3D9;
27 D3DMATRIX SphereMapMatrixD3D9;
setTextureColorStage(IDirect3DDevice9 * dev,DWORD i,DWORD arg1,DWORD op,DWORD arg2)28 inline void setTextureColorStage(IDirect3DDevice9* dev, DWORD i,
29 DWORD arg1, DWORD op, DWORD arg2)
30 {
31 dev->SetTextureStageState(i, D3DTSS_COLOROP, op);
32 dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1);
33 dev->SetTextureStageState(i, D3DTSS_COLORARG2, arg2);
34 }
setTextureColorStage(IDirect3DDevice9 * dev,DWORD i,DWORD arg1)35 inline void setTextureColorStage(IDirect3DDevice9* dev, DWORD i, DWORD arg1)
36 {
37 dev->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
38 dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1);
39 }
40
setTextureAlphaStage(IDirect3DDevice9 * dev,DWORD i,DWORD arg1,DWORD op,DWORD arg2)41 inline void setTextureAlphaStage(IDirect3DDevice9* dev, DWORD i,
42 DWORD arg1, DWORD op, DWORD arg2)
43 {
44 dev->SetTextureStageState(i, D3DTSS_ALPHAOP, op);
45 dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1);
46 dev->SetTextureStageState(i, D3DTSS_ALPHAARG2, arg2);
47 }
setTextureAlphaStage(IDirect3DDevice9 * dev,DWORD i,DWORD arg1)48 inline void setTextureAlphaStage(IDirect3DDevice9* dev, DWORD i, DWORD arg1)
49 {
50 dev->SetTextureStageState(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
51 dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1);
52 }
53 } // anonymous namespace
54
55 //! Base class for all internal D3D9 material renderers
56 class CD3D9MaterialRenderer : public IMaterialRenderer
57 {
58 public:
59
60 //! Constructor
CD3D9MaterialRenderer(IDirect3DDevice9 * d3ddev,video::IVideoDriver * driver)61 CD3D9MaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver)
62 : pID3DDevice(d3ddev), Driver(driver)
63 {
64 }
65
66 //! sets a variable in the shader.
67 //! \param vertexShader: True if this should be set in the vertex shader, false if
68 //! in the pixel shader.
69 //! \param name: Name of the variable
70 //! \param floats: Pointer to array of floats
71 //! \param count: Amount of floats in array.
setVariable(bool vertexShader,const c8 * name,const f32 * floats,int count)72 virtual bool setVariable(bool vertexShader, const c8* name, const f32* floats, int count)
73 {
74 os::Printer::log("Invalid material to set variable in.");
75 return false;
76 }
77
78 //! Bool interface for the above.
setVariable(bool vertexShader,const c8 * name,const bool * bools,int count)79 virtual bool setVariable(bool vertexShader, const c8* name, const bool* bools, int count)
80 {
81 os::Printer::log("Invalid material to set variable in.");
82 return false;
83 }
84
85 //! Int interface for the above.
setVariable(bool vertexShader,const c8 * name,const s32 * ints,int count)86 virtual bool setVariable(bool vertexShader, const c8* name, const s32* ints, int count)
87 {
88 os::Printer::log("Invalid material to set variable in.");
89 return false;
90 }
91
92 protected:
93
94 IDirect3DDevice9* pID3DDevice;
95 video::IVideoDriver* Driver;
96 };
97
98
99 //! Solid material renderer
100 class CD3D9MaterialRenderer_SOLID : public CD3D9MaterialRenderer
101 {
102 public:
103
CD3D9MaterialRenderer_SOLID(IDirect3DDevice9 * p,video::IVideoDriver * d)104 CD3D9MaterialRenderer_SOLID(IDirect3DDevice9* p, video::IVideoDriver* d)
105 : CD3D9MaterialRenderer(p, d) {}
106
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)107 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
108 bool resetAllRenderstates, IMaterialRendererServices* services)
109 {
110 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
111
112 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
113 {
114 setTextureColorStage(pID3DDevice, 0,
115 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
116 }
117
118 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
119 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
120 }
121 };
122
123 //! Generic Texture Blend
124 class CD3D9MaterialRenderer_ONETEXTURE_BLEND : public CD3D9MaterialRenderer
125 {
126 public:
127
CD3D9MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice9 * p,video::IVideoDriver * d)128 CD3D9MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice9* p, video::IVideoDriver* d)
129 : CD3D9MaterialRenderer(p, d) {}
130
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)131 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
132 bool resetAllRenderstates, IMaterialRendererServices* services)
133 {
134 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
135
136 if (material.MaterialType != lastMaterial.MaterialType ||
137 material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
138 resetAllRenderstates)
139 {
140
141 E_BLEND_FACTOR srcFact,dstFact;
142 E_MODULATE_FUNC modulate;
143 u32 alphaSource;
144 unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam );
145
146 if (srcFact == EBF_SRC_COLOR && dstFact == EBF_ZERO)
147 {
148 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
149 }
150 else
151 {
152 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
153 pID3DDevice->SetRenderState(D3DRS_SRCBLEND, getD3DBlend ( srcFact ) );
154 pID3DDevice->SetRenderState(D3DRS_DESTBLEND, getD3DBlend ( dstFact ) );
155 }
156
157 setTextureColorStage(pID3DDevice, 0,
158 D3DTA_TEXTURE, getD3DModulate(modulate), D3DTA_DIFFUSE);
159
160 if ( textureBlendFunc_hasAlpha ( srcFact ) || textureBlendFunc_hasAlpha ( dstFact ) )
161 {
162 if (alphaSource==EAS_VERTEX_COLOR)
163 {
164 setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE);
165 }
166 else if (alphaSource==EAS_TEXTURE)
167 {
168 setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE);
169 }
170 else
171 {
172 setTextureAlphaStage(pID3DDevice, 0,
173 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
174 }
175 }
176
177 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
178
179 }
180 }
181
182 //! Returns if the material is transparent.
183 /** The scene management needs to know this for being able to sort the
184 materials by opaque and transparent.
185 The return value could be optimized, but we'd need to know the
186 MaterialTypeParam for it. */
isTransparent()187 virtual bool isTransparent() const
188 {
189 return true;
190 }
191
192 private:
193
getD3DBlend(E_BLEND_FACTOR factor)194 u32 getD3DBlend ( E_BLEND_FACTOR factor ) const
195 {
196 u32 r = 0;
197 switch ( factor )
198 {
199 case EBF_ZERO: r = D3DBLEND_ZERO; break;
200 case EBF_ONE: r = D3DBLEND_ONE; break;
201 case EBF_DST_COLOR: r = D3DBLEND_DESTCOLOR; break;
202 case EBF_ONE_MINUS_DST_COLOR: r = D3DBLEND_INVDESTCOLOR; break;
203 case EBF_SRC_COLOR: r = D3DBLEND_SRCCOLOR; break;
204 case EBF_ONE_MINUS_SRC_COLOR: r = D3DBLEND_INVSRCCOLOR; break;
205 case EBF_SRC_ALPHA: r = D3DBLEND_SRCALPHA; break;
206 case EBF_ONE_MINUS_SRC_ALPHA: r = D3DBLEND_INVSRCALPHA; break;
207 case EBF_DST_ALPHA: r = D3DBLEND_DESTALPHA; break;
208 case EBF_ONE_MINUS_DST_ALPHA: r = D3DBLEND_INVDESTALPHA; break;
209 case EBF_SRC_ALPHA_SATURATE: r = D3DBLEND_SRCALPHASAT; break;
210 }
211 return r;
212 }
213
getD3DModulate(E_MODULATE_FUNC func)214 u32 getD3DModulate ( E_MODULATE_FUNC func ) const
215 {
216 u32 r = D3DTOP_MODULATE;
217 switch ( func )
218 {
219 case EMFN_MODULATE_1X: r = D3DTOP_MODULATE; break;
220 case EMFN_MODULATE_2X: r = D3DTOP_MODULATE2X; break;
221 case EMFN_MODULATE_4X: r = D3DTOP_MODULATE4X; break;
222 }
223 return r;
224 }
225
226 bool transparent;
227
228 };
229
230
231
232 //! Solid 2 layer material renderer
233 class CD3D9MaterialRenderer_SOLID_2_LAYER : public CD3D9MaterialRenderer
234 {
235 public:
236
CD3D9MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice9 * p,video::IVideoDriver * d)237 CD3D9MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d)
238 : CD3D9MaterialRenderer(p, d) {}
239
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)240 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
241 bool resetAllRenderstates, IMaterialRendererServices* services)
242 {
243 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
244
245 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
246 {
247 setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE);
248
249 pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
250 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA);
251
252 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
253 }
254 }
255 };
256
257
258 //! Transparent add color material renderer
259 class CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR : public CD3D9MaterialRenderer
260 {
261 public:
262
CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice9 * p,video::IVideoDriver * d)263 CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice9* p, video::IVideoDriver* d)
264 : CD3D9MaterialRenderer(p, d) {}
265
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)266 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
267 bool resetAllRenderstates, IMaterialRendererServices* services)
268 {
269 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
270
271 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
272 {
273 setTextureColorStage(pID3DDevice, 0,
274 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
275
276 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
277 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
278 pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
279 pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
280 }
281 }
282
283 //! Returns if the material is transparent. The scene management needs to know this
284 //! for being able to sort the materials by opaque and transparent.
isTransparent()285 virtual bool isTransparent() const
286 {
287 return true;
288 }
289 };
290
291
292 //! Transparent vertex alpha material renderer
293 class CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public CD3D9MaterialRenderer
294 {
295 public:
296
CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice9 * p,video::IVideoDriver * d)297 CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice9* p, video::IVideoDriver* d)
298 : CD3D9MaterialRenderer(p, d) {}
299
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)300 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
301 bool resetAllRenderstates, IMaterialRendererServices* services)
302 {
303 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
304
305 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
306 {
307 setTextureColorStage(pID3DDevice, 0,
308 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
309 setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE);
310
311 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
312 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
313 pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
314 pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
315 }
316 }
317
318 //! Returns if the material is transparent. The scene managment needs to know this
319 //! for being able to sort the materials by opaque and transparent.
isTransparent()320 virtual bool isTransparent() const
321 {
322 return true;
323 }
324 };
325
326
327 //! Transparent alpha channel material renderer
328 class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public CD3D9MaterialRenderer
329 {
330 public:
331
CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice9 * p,video::IVideoDriver * d)332 CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice9* p, video::IVideoDriver* d)
333 : CD3D9MaterialRenderer(p, d) {}
334
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)335 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
336 bool resetAllRenderstates, IMaterialRendererServices* services)
337 {
338 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
339
340 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates
341 || material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
342 {
343 setTextureColorStage(pID3DDevice, 0,
344 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT);
345 setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE);
346
347 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
348 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
349 pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
350 pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
351
352 pID3DDevice->SetRenderState(D3DRS_ALPHAREF, core::floor32(material.MaterialTypeParam * 255.f));
353 pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
354 pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
355 }
356 }
357
OnUnsetMaterial()358 virtual void OnUnsetMaterial()
359 {
360 pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
361 }
362
363 //! Returns if the material is transparent. The scene managment needs to know this
364 //! for being able to sort the materials by opaque and transparent.
isTransparent()365 virtual bool isTransparent() const
366 {
367 return true;
368 }
369 };
370
371
372
373 //! Transparent alpha channel material renderer
374 class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public CD3D9MaterialRenderer
375 {
376 public:
377
CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice9 * p,video::IVideoDriver * d)378 CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice9* p, video::IVideoDriver* d)
379 : CD3D9MaterialRenderer(p, d) {}
380
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)381 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
382 bool resetAllRenderstates, IMaterialRendererServices* services)
383 {
384 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
385
386 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
387 {
388 setTextureColorStage(pID3DDevice, 0,
389 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT);
390 setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE);
391
392 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
393
394 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
395
396 // 127 is required by EMT_TRANSPARENT_ALPHA_CHANNEL_REF
397 pID3DDevice->SetRenderState(D3DRS_ALPHAREF, 127);
398 pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
399 pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
400 }
401 }
402
OnUnsetMaterial()403 virtual void OnUnsetMaterial()
404 {
405 pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
406 }
407
408 //! Returns if the material is transparent. The scene managment needs to know this
409 //! for being able to sort the materials by opaque and transparent.
isTransparent()410 virtual bool isTransparent() const
411 {
412 return false; // this material is not really transparent because it does no blending.
413 }
414 };
415
416
417 //! material renderer for all kinds of lightmaps
418 class CD3D9MaterialRenderer_LIGHTMAP : public CD3D9MaterialRenderer
419 {
420 public:
421
CD3D9MaterialRenderer_LIGHTMAP(IDirect3DDevice9 * p,video::IVideoDriver * d)422 CD3D9MaterialRenderer_LIGHTMAP(IDirect3DDevice9* p, video::IVideoDriver* d)
423 : CD3D9MaterialRenderer(p, d) {}
424
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)425 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
426 bool resetAllRenderstates, IMaterialRendererServices* services)
427 {
428 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
429
430 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
431 {
432 if (material.MaterialType >= EMT_LIGHTMAP_LIGHTING)
433 {
434 // with lighting
435 setTextureColorStage(pID3DDevice, 0,
436 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
437 }
438 else
439 {
440 setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE);
441 }
442
443 pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
444
445 setTextureColorStage(pID3DDevice, 1,
446 D3DTA_TEXTURE,
447 (material.MaterialType == EMT_LIGHTMAP_ADD)?
448 D3DTOP_ADD:
449 (material.MaterialType == EMT_LIGHTMAP_M4 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M4)?
450 D3DTOP_MODULATE4X:
451 (material.MaterialType == EMT_LIGHTMAP_M2 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M2)?
452 D3DTOP_MODULATE2X:
453 D3DTOP_MODULATE,
454 D3DTA_CURRENT);
455
456 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
457 }
458 }
459 };
460
461
462
463 //! material renderer for detail maps
464 class CD3D9MaterialRenderer_DETAIL_MAP : public CD3D9MaterialRenderer
465 {
466 public:
467
CD3D9MaterialRenderer_DETAIL_MAP(IDirect3DDevice9 * p,video::IVideoDriver * d)468 CD3D9MaterialRenderer_DETAIL_MAP(IDirect3DDevice9* p, video::IVideoDriver* d)
469 : CD3D9MaterialRenderer(p, d) {}
470
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)471 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
472 bool resetAllRenderstates, IMaterialRendererServices* services)
473 {
474 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
475
476 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
477 {
478 setTextureColorStage(pID3DDevice, 0,
479 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
480 setTextureColorStage(pID3DDevice, 1,
481 D3DTA_TEXTURE, D3DTOP_ADDSIGNED, D3DTA_CURRENT);
482 pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
483 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
484 }
485 }
486 };
487
488
489 //! sphere map material renderer
490 class CD3D9MaterialRenderer_SPHERE_MAP : public CD3D9MaterialRenderer
491 {
492 public:
493
CD3D9MaterialRenderer_SPHERE_MAP(IDirect3DDevice9 * p,video::IVideoDriver * d)494 CD3D9MaterialRenderer_SPHERE_MAP(IDirect3DDevice9* p, video::IVideoDriver* d)
495 : CD3D9MaterialRenderer(p, d) {}
496
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)497 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
498 bool resetAllRenderstates, IMaterialRendererServices* services)
499 {
500 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
501
502 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
503 {
504 setTextureColorStage(pID3DDevice, 0,
505 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
506
507 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
508 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
509
510 pID3DDevice->SetTransform( D3DTS_TEXTURE0, &SphereMapMatrixD3D9 );
511 pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
512 pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL );
513 }
514 }
515
OnUnsetMaterial()516 virtual void OnUnsetMaterial()
517 {
518 pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
519 pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0);
520 pID3DDevice->SetTransform( D3DTS_TEXTURE0, &UnitMatrixD3D9 );
521 }
522 };
523
524
525 //! reflection 2 layer material renderer
526 class CD3D9MaterialRenderer_REFLECTION_2_LAYER : public CD3D9MaterialRenderer
527 {
528 public:
529
CD3D9MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice9 * p,video::IVideoDriver * d)530 CD3D9MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d)
531 : CD3D9MaterialRenderer(p, d) {}
532
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)533 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
534 bool resetAllRenderstates, IMaterialRendererServices* services)
535 {
536 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
537
538 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
539 {
540 setTextureColorStage(pID3DDevice, 0,
541 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
542
543 setTextureColorStage(pID3DDevice, 1,
544 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT);
545
546 pID3DDevice->SetTransform( D3DTS_TEXTURE1, &SphereMapMatrixD3D9 );
547 pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
548 pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
549 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
550 }
551 }
552
OnUnsetMaterial()553 virtual void OnUnsetMaterial()
554 {
555 pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
556 pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1);
557 pID3DDevice->SetTransform( D3DTS_TEXTURE1, &UnitMatrixD3D9 );
558 }
559 };
560
561
562 //! reflection 2 layer material renderer
563 class CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public CD3D9MaterialRenderer
564 {
565 public:
566
CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice9 * p,video::IVideoDriver * d)567 CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d)
568 : CD3D9MaterialRenderer(p, d) {}
569
OnSetMaterial(const SMaterial & material,const SMaterial & lastMaterial,bool resetAllRenderstates,IMaterialRendererServices * services)570 virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
571 bool resetAllRenderstates, IMaterialRendererServices* services)
572 {
573 services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
574
575 if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
576 {
577 setTextureColorStage(pID3DDevice, 0,
578 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE);
579 setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE);
580 setTextureColorStage(pID3DDevice, 1,
581 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT);
582 setTextureAlphaStage(pID3DDevice, 1, D3DTA_CURRENT);
583
584 pID3DDevice->SetTransform(D3DTS_TEXTURE1, &SphereMapMatrixD3D9 );
585 pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
586 pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
587
588 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
589 pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
590 pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
591 }
592 }
593
OnUnsetMaterial()594 virtual void OnUnsetMaterial()
595 {
596 pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
597 pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
598 pID3DDevice->SetTransform(D3DTS_TEXTURE1, &UnitMatrixD3D9);
599 }
600
601 //! Returns if the material is transparent. The scene managment needs to know this
602 //! for being able to sort the materials by opaque and transparent.
isTransparent()603 virtual bool isTransparent() const
604 {
605 return true;
606 }
607 };
608
609 } // end namespace video
610 } // end namespace irr
611
612 #endif
613 #endif
614 #endif
615
616