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