]> git.lizzy.rs Git - irrlicht.git/blob - include/SMaterial.h
Reduce IrrCompileConfig usage to files that actually need it
[irrlicht.git] / include / SMaterial.h
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 #ifndef __S_MATERIAL_H_INCLUDED__\r
6 #define __S_MATERIAL_H_INCLUDED__\r
7 \r
8 #include "SColor.h"\r
9 #include "matrix4.h"\r
10 #include "irrArray.h"\r
11 #include "irrMath.h"\r
12 #include "EMaterialTypes.h"\r
13 #include "EMaterialFlags.h"\r
14 #include "SMaterialLayer.h"\r
15 #include "IrrCompileConfig.h" // for IRRLICHT_API\r
16 \r
17 namespace irr\r
18 {\r
19 namespace video\r
20 {\r
21         class ITexture;\r
22 \r
23         //! Flag for MaterialTypeParam (in combination with EMT_ONETEXTURE_BLEND) or for BlendFactor\r
24         //! BlendFunc = source * sourceFactor + dest * destFactor\r
25         enum E_BLEND_FACTOR\r
26         {\r
27                 EBF_ZERO        = 0,            //!< src & dest (0, 0, 0, 0)\r
28                 EBF_ONE,                        //!< src & dest (1, 1, 1, 1)\r
29                 EBF_DST_COLOR,                  //!< src        (destR, destG, destB, destA)\r
30                 EBF_ONE_MINUS_DST_COLOR,        //!< src        (1-destR, 1-destG, 1-destB, 1-destA)\r
31                 EBF_SRC_COLOR,                  //!< dest       (srcR, srcG, srcB, srcA)\r
32                 EBF_ONE_MINUS_SRC_COLOR,        //!< dest       (1-srcR, 1-srcG, 1-srcB, 1-srcA)\r
33                 EBF_SRC_ALPHA,                  //!< src & dest (srcA, srcA, srcA, srcA)\r
34                 EBF_ONE_MINUS_SRC_ALPHA,        //!< src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA)\r
35                 EBF_DST_ALPHA,                  //!< src & dest (destA, destA, destA, destA)\r
36                 EBF_ONE_MINUS_DST_ALPHA,        //!< src & dest (1-destA, 1-destA, 1-destA, 1-destA)\r
37                 EBF_SRC_ALPHA_SATURATE          //!< src        (min(srcA, 1-destA), idem, ...)\r
38         };\r
39 \r
40         //! Values defining the blend operation\r
41         enum E_BLEND_OPERATION\r
42         {\r
43                 EBO_NONE = 0,   //!< No blending happens\r
44                 EBO_ADD,        //!< Default blending adds the color values\r
45                 EBO_SUBTRACT,   //!< This mode subtracts the color values\r
46                 EBO_REVSUBTRACT,//!< This modes subtracts destination from source\r
47                 EBO_MIN,        //!< Choose minimum value of each color channel\r
48                 EBO_MAX,        //!< Choose maximum value of each color channel\r
49                 EBO_MIN_FACTOR, //!< Choose minimum value of each color channel after applying blend factors, not widely supported\r
50                 EBO_MAX_FACTOR, //!< Choose maximum value of each color channel after applying blend factors, not widely supported\r
51                 EBO_MIN_ALPHA,  //!< Choose minimum value of each color channel based on alpha value, not widely supported\r
52                 EBO_MAX_ALPHA   //!< Choose maximum value of each color channel based on alpha value, not widely supported\r
53         };\r
54 \r
55         //! MaterialTypeParam: e.g. DirectX: D3DTOP_MODULATE, D3DTOP_MODULATE2X, D3DTOP_MODULATE4X\r
56         enum E_MODULATE_FUNC\r
57         {\r
58                 EMFN_MODULATE_1X        = 1,\r
59                 EMFN_MODULATE_2X        = 2,\r
60                 EMFN_MODULATE_4X        = 4\r
61         };\r
62 \r
63         //! Comparison function, e.g. for depth buffer test\r
64         enum E_COMPARISON_FUNC\r
65         {\r
66                 //! Depth test disabled (disable also write to depth buffer)\r
67                 ECFN_DISABLED=0,\r
68                 //! <= test, default for e.g. depth test\r
69                 ECFN_LESSEQUAL=1,\r
70                 //! Exact equality\r
71                 ECFN_EQUAL=2,\r
72                 //! exclusive less comparison, i.e. <\r
73                 ECFN_LESS,\r
74                 //! Succeeds almost always, except for exact equality\r
75                 ECFN_NOTEQUAL,\r
76                 //! >= test\r
77                 ECFN_GREATEREQUAL,\r
78                 //! inverse of <=\r
79                 ECFN_GREATER,\r
80                 //! test succeeds always\r
81                 ECFN_ALWAYS,\r
82                 //! Test never succeeds\r
83                 ECFN_NEVER\r
84         };\r
85 \r
86         //! Enum values for enabling/disabling color planes for rendering\r
87         enum E_COLOR_PLANE\r
88         {\r
89                 //! No color enabled\r
90                 ECP_NONE=0,\r
91                 //! Alpha enabled\r
92                 ECP_ALPHA=1,\r
93                 //! Red enabled\r
94                 ECP_RED=2,\r
95                 //! Green enabled\r
96                 ECP_GREEN=4,\r
97                 //! Blue enabled\r
98                 ECP_BLUE=8,\r
99                 //! All colors, no alpha\r
100                 ECP_RGB=14,\r
101                 //! All planes enabled\r
102                 ECP_ALL=15\r
103         };\r
104 \r
105         //! Source of the alpha value to take\r
106         /** This is currently only supported in EMT_ONETEXTURE_BLEND. You can use an\r
107         or'ed combination of values. Alpha values are modulated (multiplied). */\r
108         enum E_ALPHA_SOURCE\r
109         {\r
110                 //! Use no alpha, somewhat redundant with other settings\r
111                 EAS_NONE=0,\r
112                 //! Use vertex color alpha\r
113                 EAS_VERTEX_COLOR,\r
114                 //! Use texture alpha channel\r
115                 EAS_TEXTURE\r
116         };\r
117 \r
118         //! Pack srcFact, dstFact, Modulate and alpha source to MaterialTypeParam or BlendFactor\r
119         /** alpha source can be an OR'ed combination of E_ALPHA_SOURCE values. */\r
120         inline f32 pack_textureBlendFunc(const E_BLEND_FACTOR srcFact, const E_BLEND_FACTOR dstFact,\r
121                         const E_MODULATE_FUNC modulate=EMFN_MODULATE_1X, const u32 alphaSource=EAS_TEXTURE)\r
122         {\r
123                 const u32 tmp = (alphaSource << 20) | (modulate << 16) | (srcFact << 12) | (dstFact << 8) | (srcFact << 4) | dstFact;\r
124                 return FR(tmp);\r
125         }\r
126 \r
127         //! Pack srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, Modulate and alpha source to MaterialTypeParam or BlendFactor\r
128         /** alpha source can be an OR'ed combination of E_ALPHA_SOURCE values. */\r
129         inline f32 pack_textureBlendFuncSeparate(const E_BLEND_FACTOR srcRGBFact, const E_BLEND_FACTOR dstRGBFact,\r
130                         const E_BLEND_FACTOR srcAlphaFact, const E_BLEND_FACTOR dstAlphaFact,\r
131                         const E_MODULATE_FUNC modulate=EMFN_MODULATE_1X, const u32 alphaSource=EAS_TEXTURE)\r
132         {\r
133                 const u32 tmp = (alphaSource << 20) | (modulate << 16) | (srcAlphaFact << 12) | (dstAlphaFact << 8) | (srcRGBFact << 4) | dstRGBFact;\r
134                 return FR(tmp);\r
135         }\r
136 \r
137         //! Unpack srcFact, dstFact, modulo and alphaSource factors\r
138         /** The fields don't use the full byte range, so we could pack even more... */\r
139         inline void unpack_textureBlendFunc(E_BLEND_FACTOR &srcFact, E_BLEND_FACTOR &dstFact,\r
140                         E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param)\r
141         {\r
142                 const u32 state = IR(param);\r
143                 alphaSource = (state & 0x00F00000) >> 20;\r
144                 modulo = E_MODULATE_FUNC( ( state & 0x000F0000 ) >> 16 );\r
145                 srcFact = E_BLEND_FACTOR ( ( state & 0x000000F0 ) >> 4 );\r
146                 dstFact = E_BLEND_FACTOR ( ( state & 0x0000000F ) );\r
147         }\r
148 \r
149         //! Unpack srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulo and alphaSource factors\r
150         /** The fields don't use the full byte range, so we could pack even more... */\r
151         inline void unpack_textureBlendFuncSeparate(E_BLEND_FACTOR &srcRGBFact, E_BLEND_FACTOR &dstRGBFact,\r
152                         E_BLEND_FACTOR &srcAlphaFact, E_BLEND_FACTOR &dstAlphaFact,\r
153                         E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param)\r
154         {\r
155                 const u32 state = IR(param);\r
156                 alphaSource = (state & 0x00F00000) >> 20;\r
157                 modulo = E_MODULATE_FUNC( ( state & 0x000F0000 ) >> 16 );\r
158                 srcAlphaFact = E_BLEND_FACTOR ( ( state & 0x0000F000 ) >> 12 );\r
159                 dstAlphaFact = E_BLEND_FACTOR ( ( state & 0x00000F00 ) >> 8 );\r
160                 srcRGBFact = E_BLEND_FACTOR ( ( state & 0x000000F0 ) >> 4 );\r
161                 dstRGBFact = E_BLEND_FACTOR ( ( state & 0x0000000F ) );\r
162         }\r
163 \r
164         //! has blend factor alphablending\r
165         inline bool textureBlendFunc_hasAlpha ( const E_BLEND_FACTOR factor )\r
166         {\r
167                 switch ( factor )\r
168                 {\r
169                         case EBF_SRC_ALPHA:\r
170                         case EBF_ONE_MINUS_SRC_ALPHA:\r
171                         case EBF_DST_ALPHA:\r
172                         case EBF_ONE_MINUS_DST_ALPHA:\r
173                         case EBF_SRC_ALPHA_SATURATE:\r
174                                 return true;\r
175                         default:\r
176                                 return false;\r
177                 }\r
178         }\r
179 \r
180 \r
181         //! These flags are used to specify the anti-aliasing and smoothing modes\r
182         /** Techniques supported are multisampling, geometry smoothing, and alpha\r
183         to coverage.\r
184         Some drivers don't support a per-material setting of the anti-aliasing\r
185         modes. In those cases, FSAA/multisampling is defined by the device mode\r
186         chosen upon creation via irr::SIrrCreationParameters.\r
187         */\r
188         enum E_ANTI_ALIASING_MODE\r
189         {\r
190                 //! Use to turn off anti-aliasing for this material\r
191                 EAAM_OFF=0,\r
192                 //! Default anti-aliasing mode\r
193                 EAAM_SIMPLE=1,\r
194                 //! High-quality anti-aliasing, not always supported, automatically enables SIMPLE mode\r
195                 EAAM_QUALITY=3,\r
196                 //! Line smoothing\r
197                 //! Careful, enabling this can lead to software emulation under OpenGL\r
198                 EAAM_LINE_SMOOTH=4,\r
199                 //! point smoothing, often in software and slow, only with OpenGL\r
200                 EAAM_POINT_SMOOTH=8,\r
201                 //! All typical anti-alias and smooth modes\r
202                 EAAM_FULL_BASIC=15,\r
203                 //! Enhanced anti-aliasing for transparent materials\r
204                 /** Usually used with EMT_TRANSPARENT_ALPHA_CHANNEL_REF and multisampling. */\r
205                 EAAM_ALPHA_TO_COVERAGE=16\r
206         };\r
207 \r
208         //! These flags allow to define the interpretation of vertex color when lighting is enabled\r
209         /** Without lighting being enabled the vertex color is the only value defining the fragment color.\r
210         Once lighting is enabled, the four values for diffuse, ambient, emissive, and specular take over.\r
211         With these flags it is possible to define which lighting factor shall be defined by the vertex color\r
212         instead of the lighting factor which is the same for all faces of that material.\r
213         The default is to use vertex color for the diffuse value, another pretty common value is to use\r
214         vertex color for both diffuse and ambient factor. */\r
215         enum E_COLOR_MATERIAL\r
216         {\r
217                 //! Don't use vertex color for lighting\r
218                 ECM_NONE=0,\r
219                 //! Use vertex color for diffuse light, this is default\r
220                 ECM_DIFFUSE,\r
221                 //! Use vertex color for ambient light\r
222                 ECM_AMBIENT,\r
223                 //! Use vertex color for emissive light\r
224                 ECM_EMISSIVE,\r
225                 //! Use vertex color for specular light\r
226                 ECM_SPECULAR,\r
227                 //! Use vertex color for both diffuse and ambient light\r
228                 ECM_DIFFUSE_AND_AMBIENT\r
229         };\r
230 \r
231         //! DEPRECATED. Will be removed after Irrlicht 1.9.\r
232         /** Flags for the definition of the polygon offset feature. These flags define whether the offset should be into the screen, or towards the eye. */\r
233         enum E_POLYGON_OFFSET\r
234         {\r
235                 //! Push pixel towards the far plane, away from the eye\r
236                 /** This is typically used for rendering inner areas. */\r
237                 EPO_BACK=0,\r
238                 //! Pull pixels towards the camera.\r
239                 /** This is typically used for polygons which should appear on top\r
240                 of other elements, such as decals. */\r
241                 EPO_FRONT=1\r
242         };\r
243 \r
244         //! Names for polygon offset direction\r
245         const c8* const PolygonOffsetDirectionNames[] =\r
246         {\r
247                 "Back",\r
248                 "Front",\r
249                 0\r
250         };\r
251 \r
252         //! For SMaterial.ZWriteEnable\r
253         enum E_ZWRITE\r
254         {\r
255                 //! zwrite always disabled for this material\r
256                 EZW_OFF = 0,\r
257 \r
258                 //! This is the default setting for SMaterial and tries to handle things automatically.\r
259                 //! This is also the value which is set when SMaterial::setFlag(EMF_ZWRITE_ENABLE) is enabled.\r
260                 //! Usually zwriting is enabled non-transparent materials - as far as Irrlicht can recognize those.\r
261                 //! Basically Irrlicht tries to handle the zwriting for you and assumes transparent materials don't need it.\r
262                 //! This is addionally affected by IVideoDriver::setAllowZWriteOnTransparent\r
263                 EZW_AUTO,\r
264 \r
265                 //! zwrite always enabled for this material\r
266                 EZW_ON\r
267         };\r
268 \r
269         //! Names for E_ZWRITE\r
270         const c8* const ZWriteNames[] =\r
271         {\r
272                 "Off",\r
273                 "Auto",\r
274                 "On",\r
275                 0\r
276         };\r
277 \r
278 \r
279 \r
280         //! Maximum number of texture an SMaterial can have.\r
281         /** SMaterial might ignore some textures in most function, like assignment and comparison,\r
282                 when SIrrlichtCreationParameters::MaxTextureUnits is set to a lower number.\r
283         */\r
284         const u32 MATERIAL_MAX_TEXTURES = 4;\r
285 \r
286         //! Struct for holding parameters for a material renderer\r
287         // Note for implementors: Serialization is in CNullDriver\r
288         class SMaterial\r
289         {\r
290         public:\r
291                 //! Default constructor. Creates a solid, lit material with white colors\r
292                 SMaterial()\r
293                 : MaterialType(EMT_SOLID), AmbientColor(255,255,255,255), DiffuseColor(255,255,255,255),\r
294                         EmissiveColor(0,0,0,0), SpecularColor(255,255,255,255),\r
295                         Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f),\r
296                         ZBuffer(ECFN_LESSEQUAL), AntiAliasing(EAAM_SIMPLE), ColorMask(ECP_ALL),\r
297                         ColorMaterial(ECM_DIFFUSE), BlendOperation(EBO_NONE), BlendFactor(0.0f),\r
298                         PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT),\r
299                         PolygonOffsetDepthBias(0.f), PolygonOffsetSlopeScale(0.f),\r
300                         Wireframe(false), PointCloud(false), GouraudShading(true),\r
301                         Lighting(true), ZWriteEnable(EZW_AUTO), BackfaceCulling(true), FrontfaceCulling(false),\r
302                         FogEnable(false), NormalizeNormals(false), UseMipMaps(true)\r
303                 { }\r
304 \r
305                 //! Texture layer array.\r
306                 SMaterialLayer TextureLayer[MATERIAL_MAX_TEXTURES];\r
307 \r
308                 //! Type of the material. Specifies how everything is blended together\r
309                 E_MATERIAL_TYPE MaterialType;\r
310 \r
311                 //! How much ambient light (a global light) is reflected by this material.\r
312                 /** The default is full white, meaning objects are completely\r
313                 globally illuminated. Reduce this if you want to see diffuse\r
314                 or specular light effects. */\r
315                 SColor AmbientColor;\r
316 \r
317                 //! How much diffuse light coming from a light source is reflected by this material.\r
318                 /** The default is full white. */\r
319                 SColor DiffuseColor;\r
320 \r
321                 //! Light emitted by this material. Default is to emit no light.\r
322                 SColor EmissiveColor;\r
323 \r
324                 //! How much specular light (highlights from a light) is reflected.\r
325                 /** The default is to reflect white specular light. See\r
326                 SMaterial::Shininess on how to enable specular lights. */\r
327                 SColor SpecularColor;\r
328 \r
329                 //! Value affecting the size of specular highlights.\r
330                 /** A value of 20 is common. If set to 0, no specular\r
331                 highlights are being used. To activate, simply set the\r
332                 shininess of a material to a value in the range [0.5;128]:\r
333                 \code\r
334                 sceneNode->getMaterial(0).Shininess = 20.0f;\r
335                 \endcode\r
336 \r
337                 You can change the color of the highlights using\r
338                 \code\r
339                 sceneNode->getMaterial(0).SpecularColor.set(255,255,255,255);\r
340                 \endcode\r
341 \r
342                 The specular color of the dynamic lights\r
343                 (SLight::SpecularColor) will influence the the highlight color\r
344                 too, but they are set to a useful value by default when\r
345                 creating the light scene node.*/\r
346                 f32 Shininess;\r
347 \r
348                 //! Free parameter, dependent on the material type.\r
349                 /** Mostly ignored, used for example in\r
350                 EMT_TRANSPARENT_ALPHA_CHANNEL and EMT_ONETEXTURE_BLEND. */\r
351                 f32 MaterialTypeParam;\r
352 \r
353                 //! Second free parameter, dependent on the material type.\r
354                 /** Mostly ignored. */\r
355                 f32 MaterialTypeParam2;\r
356 \r
357                 //! Thickness of non-3dimensional elements such as lines and points.\r
358                 f32 Thickness;\r
359 \r
360                 //! Is the ZBuffer enabled? Default: ECFN_LESSEQUAL\r
361                 /** If you want to disable depth test for this material\r
362                 just set this parameter to ECFN_DISABLED.\r
363                 Values are from E_COMPARISON_FUNC. */\r
364                 u8 ZBuffer;\r
365 \r
366                 //! Sets the antialiasing mode\r
367                 /** Values are chosen from E_ANTI_ALIASING_MODE. Default is\r
368                 EAAM_SIMPLE, i.e. simple multi-sample anti-aliasing. */\r
369                 u8 AntiAliasing;\r
370 \r
371                 //! Defines the enabled color planes\r
372                 /** Values are defined as or'ed values of the E_COLOR_PLANE enum.\r
373                 Only enabled color planes will be rendered to the current render\r
374                 target. Typical use is to disable all colors when rendering only to\r
375                 depth or stencil buffer, or using Red and Green for Stereo rendering. */\r
376                 u8 ColorMask:4;\r
377 \r
378                 //! Defines the interpretation of vertex color in the lighting equation\r
379                 /** Values should be chosen from E_COLOR_MATERIAL.\r
380                 When lighting is enabled, vertex color can be used instead of the\r
381                 material values for light modulation. This allows to easily change e.g. the\r
382                 diffuse light behavior of each face. The default, ECM_DIFFUSE, will result in\r
383                 a very similar rendering as with lighting turned off, just with light shading. */\r
384                 u8 ColorMaterial:3;\r
385 \r
386                 //! Store the blend operation of choice\r
387                 /** Values to be chosen from E_BLEND_OPERATION. */\r
388                 E_BLEND_OPERATION BlendOperation:4;\r
389 \r
390                 //! Store the blend factors\r
391                 /** textureBlendFunc/textureBlendFuncSeparate functions should be used to write\r
392                 properly blending factors to this parameter. \r
393                 Due to historical reasons this parameter is not used for material type \r
394                 EMT_ONETEXTURE_BLEND which uses MaterialTypeParam instead for the blend factor.\r
395                 It's generally used only for materials without any blending otherwise (like EMT_SOLID).\r
396                 It's main use is to allow having shader materials which can enable/disable \r
397                 blending after they have been created. \r
398                 When you set this you usually also have to set BlendOperation to a value != EBO_NONE\r
399                 (setting it to EBO_ADD is probably the most common one value). */\r
400                 f32 BlendFactor;\r
401 \r
402                 //! DEPRECATED. Will be removed after Irrlicht 1.9. Please use PolygonOffsetDepthBias instead.\r
403                 /** Factor specifying how far the polygon offset should be made.\r
404                 Specifying 0 disables the polygon offset. The direction is specified separately.\r
405                 The factor can be from 0 to 7.\r
406                 Note: This probably never worked on Direct3D9 (was coded for D3D8 which had different value ranges)     */\r
407                 u8 PolygonOffsetFactor:3;\r
408 \r
409                 //! DEPRECATED. Will be removed after Irrlicht 1.9.\r
410                 /** Flag defining the direction the polygon offset is applied to.\r
411                 Can be to front or to back, specified by values from E_POLYGON_OFFSET.  */\r
412                 E_POLYGON_OFFSET PolygonOffsetDirection:1;\r
413 \r
414                 //! A constant z-buffer offset for a polygon/line/point\r
415                 /** The range of the value is driver specific.\r
416                 On OpenGL you get units which are multiplied by the smallest value that is guaranteed to produce a resolvable offset.\r
417                 On D3D9 you can pass a range between -1 and 1. But you should likely divide it by the range of the depthbuffer.\r
418                 Like dividing by 65535.0 for a 16 bit depthbuffer. Thought it still might produce too large of a bias.\r
419                 Some article (https://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/)\r
420                 recommends multiplying by 2.0*4.8e-7 (and strangely on both 16 bit and 24 bit). */\r
421                 f32 PolygonOffsetDepthBias;\r
422 \r
423                 //! Variable Z-Buffer offset based on the slope of the polygon.\r
424                 /** For polygons looking flat at a camera you could use 0 (for example in a 2D game)\r
425                 But in most cases you will have polygons rendered at a certain slope.\r
426                 The driver will calculate the slope for you and this value allows to scale that slope.\r
427                 The complete polygon offset is: PolygonOffsetSlopeScale*slope + PolygonOffsetDepthBias\r
428                 A good default here is to use 1.f if you want to push the polygons away from the camera\r
429                 and -1.f to pull them towards the camera.  */\r
430                 f32 PolygonOffsetSlopeScale;\r
431 \r
432                 //! Draw as wireframe or filled triangles? Default: false\r
433                 /** The user can access a material flag using\r
434                 \code material.Wireframe=true \endcode\r
435                 or \code material.setFlag(EMF_WIREFRAME, true); \endcode */\r
436                 bool Wireframe:1;\r
437 \r
438                 //! Draw as point cloud or filled triangles? Default: false\r
439                 bool PointCloud:1;\r
440 \r
441                 //! Flat or Gouraud shading? Default: true\r
442                 bool GouraudShading:1;\r
443 \r
444                 //! Will this material be lighted? Default: true\r
445                 bool Lighting:1;\r
446 \r
447                 //! Is the zbuffer writable or is it read-only. Default: EZW_AUTO.\r
448                 /** If this parameter is not EZW_OFF, you probably also want to set ZBuffer \r
449                 to values other than ECFN_DISABLED */\r
450                 E_ZWRITE ZWriteEnable:2;\r
451 \r
452                 //! Is backface culling enabled? Default: true\r
453                 bool BackfaceCulling:1;\r
454 \r
455                 //! Is frontface culling enabled? Default: false\r
456                 bool FrontfaceCulling:1;\r
457 \r
458                 //! Is fog enabled? Default: false\r
459                 bool FogEnable:1;\r
460 \r
461                 //! Should normals be normalized?\r
462                 /** Always use this if the mesh lit and scaled. Default: false */\r
463                 bool NormalizeNormals:1;\r
464 \r
465                 //! Shall mipmaps be used if available\r
466                 /** Sometimes, disabling mipmap usage can be useful. Default: true */\r
467                 bool UseMipMaps:1;\r
468 \r
469                 //! Gets the texture transformation matrix for level i\r
470                 /** \param i The desired level. Must not be larger than MATERIAL_MAX_TEXTURES\r
471                 \return Texture matrix for texture level i. */\r
472                 core::matrix4& getTextureMatrix(u32 i)\r
473                 {\r
474                         return TextureLayer[i].getTextureMatrix();\r
475                 }\r
476 \r
477                 //! Gets the immutable texture transformation matrix for level i\r
478                 /** \param i The desired level.\r
479                 \return Texture matrix for texture level i, or identity matrix for levels larger than MATERIAL_MAX_TEXTURES. */\r
480                 const core::matrix4& getTextureMatrix(u32 i) const\r
481                 {\r
482                         if (i<MATERIAL_MAX_TEXTURES)\r
483                                 return TextureLayer[i].getTextureMatrix();\r
484                         else\r
485                                 return core::IdentityMatrix;\r
486                 }\r
487 \r
488                 //! Sets the i-th texture transformation matrix\r
489                 /** \param i The desired level.\r
490                 \param mat Texture matrix for texture level i. */\r
491                 void setTextureMatrix(u32 i, const core::matrix4& mat)\r
492                 {\r
493                         if (i>=MATERIAL_MAX_TEXTURES)\r
494                                 return;\r
495                         TextureLayer[i].setTextureMatrix(mat);\r
496                 }\r
497 \r
498                 //! Gets the i-th texture\r
499                 /** \param i The desired level.\r
500                 \return Texture for texture level i, if defined, else 0. */\r
501                 ITexture* getTexture(u32 i) const\r
502                 {\r
503                         return i < MATERIAL_MAX_TEXTURES ? TextureLayer[i].Texture : 0;\r
504                 }\r
505 \r
506                 //! Sets the i-th texture\r
507                 /** If i>=MATERIAL_MAX_TEXTURES this setting will be ignored.\r
508                 \param i The desired level.\r
509                 \param tex Texture for texture level i. */\r
510                 void setTexture(u32 i, ITexture* tex)\r
511                 {\r
512                         if (i>=MATERIAL_MAX_TEXTURES)\r
513                                 return;\r
514                         TextureLayer[i].Texture = tex;\r
515                 }\r
516 \r
517                 //! Sets the Material flag to the given value\r
518                 /** \param flag The flag to be set.\r
519                 \param value The new value for the flag. */\r
520                 void setFlag(E_MATERIAL_FLAG flag, bool value)\r
521                 {\r
522                         switch (flag)\r
523                         {\r
524                                 case EMF_WIREFRAME:\r
525                                         Wireframe = value; break;\r
526                                 case EMF_POINTCLOUD:\r
527                                         PointCloud = value; break;\r
528                                 case EMF_GOURAUD_SHADING:\r
529                                         GouraudShading = value; break;\r
530                                 case EMF_LIGHTING:\r
531                                         Lighting = value; break;\r
532                                 case EMF_ZBUFFER:\r
533                                         ZBuffer = value; break;\r
534                                 case EMF_ZWRITE_ENABLE:\r
535                                         ZWriteEnable = value ? EZW_AUTO : EZW_OFF; break;\r
536                                 case EMF_BACK_FACE_CULLING:\r
537                                         BackfaceCulling = value; break;\r
538                                 case EMF_FRONT_FACE_CULLING:\r
539                                         FrontfaceCulling = value; break;\r
540                                 case EMF_BILINEAR_FILTER:\r
541                                 {\r
542                                         for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)\r
543                                                 TextureLayer[i].BilinearFilter = value;\r
544                                 }\r
545                                 break;\r
546                                 case EMF_TRILINEAR_FILTER:\r
547                                 {\r
548                                         for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)\r
549                                                 TextureLayer[i].TrilinearFilter = value;\r
550                                 }\r
551                                 break;\r
552                                 case EMF_ANISOTROPIC_FILTER:\r
553                                 {\r
554                                         if (value)\r
555                                                 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)\r
556                                                         TextureLayer[i].AnisotropicFilter = 0xFF;\r
557                                         else\r
558                                                 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)\r
559                                                         TextureLayer[i].AnisotropicFilter = 0;\r
560                                 }\r
561                                 break;\r
562                                 case EMF_FOG_ENABLE:\r
563                                         FogEnable = value; break;\r
564                                 case EMF_NORMALIZE_NORMALS:\r
565                                         NormalizeNormals = value; break;\r
566                                 case EMF_TEXTURE_WRAP:\r
567                                 {\r
568                                         for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)\r
569                                         {\r
570                                                 TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)value;\r
571                                                 TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)value;\r
572                                                 TextureLayer[i].TextureWrapW = (E_TEXTURE_CLAMP)value;\r
573                                         }\r
574                                 }\r
575                                 break;\r
576                                 case EMF_ANTI_ALIASING:\r
577                                         AntiAliasing = value?EAAM_SIMPLE:EAAM_OFF; break;\r
578                                 case EMF_COLOR_MASK:\r
579                                         ColorMask = value?ECP_ALL:ECP_NONE; break;\r
580                                 case EMF_COLOR_MATERIAL:\r
581                                         ColorMaterial = value?ECM_DIFFUSE:ECM_NONE; break;\r
582                                 case EMF_USE_MIP_MAPS:\r
583                                         UseMipMaps = value; break;\r
584                                 case EMF_BLEND_OPERATION:\r
585                                         BlendOperation = value?EBO_ADD:EBO_NONE; break;\r
586                                 case EMF_BLEND_FACTOR:\r
587                                         break;\r
588                                 case EMF_POLYGON_OFFSET:\r
589                                         PolygonOffsetFactor = value?1:0;\r
590                                         PolygonOffsetDirection = EPO_BACK;\r
591                                         PolygonOffsetSlopeScale = value?1.f:0.f;\r
592                                         PolygonOffsetDepthBias = value?1.f:0.f;\r
593                                 default:\r
594                                         break;\r
595                         }\r
596                 }\r
597 \r
598                 //! Gets the Material flag\r
599                 /** \param flag The flag to query.\r
600                 \return The current value of the flag. */\r
601                 bool getFlag(E_MATERIAL_FLAG flag) const\r
602                 {\r
603                         switch (flag)\r
604                         {\r
605                                 case EMF_WIREFRAME:\r
606                                         return Wireframe;\r
607                                 case EMF_POINTCLOUD:\r
608                                         return PointCloud;\r
609                                 case EMF_GOURAUD_SHADING:\r
610                                         return GouraudShading;\r
611                                 case EMF_LIGHTING:\r
612                                         return Lighting;\r
613                                 case EMF_ZBUFFER:\r
614                                         return ZBuffer!=ECFN_DISABLED;\r
615                                 case EMF_ZWRITE_ENABLE:\r
616                                         return ZWriteEnable != EZW_OFF;\r
617                                 case EMF_BACK_FACE_CULLING:\r
618                                         return BackfaceCulling;\r
619                                 case EMF_FRONT_FACE_CULLING:\r
620                                         return FrontfaceCulling;\r
621                                 case EMF_BILINEAR_FILTER:\r
622                                         return TextureLayer[0].BilinearFilter;\r
623                                 case EMF_TRILINEAR_FILTER:\r
624                                         return TextureLayer[0].TrilinearFilter;\r
625                                 case EMF_ANISOTROPIC_FILTER:\r
626                                         return TextureLayer[0].AnisotropicFilter!=0;\r
627                                 case EMF_FOG_ENABLE:\r
628                                         return FogEnable;\r
629                                 case EMF_NORMALIZE_NORMALS:\r
630                                         return NormalizeNormals;\r
631                                 case EMF_TEXTURE_WRAP:\r
632                                         return !(TextureLayer[0].TextureWrapU ||\r
633                                                         TextureLayer[0].TextureWrapV ||\r
634                                                         TextureLayer[0].TextureWrapW);\r
635                                 case EMF_ANTI_ALIASING:\r
636                                         return (AntiAliasing==1);\r
637                                 case EMF_COLOR_MASK:\r
638                                         return (ColorMask!=ECP_NONE);\r
639                                 case EMF_COLOR_MATERIAL:\r
640                                         return (ColorMaterial != ECM_NONE);\r
641                                 case EMF_USE_MIP_MAPS:\r
642                                         return UseMipMaps;\r
643                                 case EMF_BLEND_OPERATION:\r
644                                         return BlendOperation != EBO_NONE;\r
645                                 case EMF_BLEND_FACTOR:\r
646                                         return BlendFactor != 0.f;\r
647                                 case EMF_POLYGON_OFFSET:\r
648                                         return PolygonOffsetFactor != 0 || PolygonOffsetDepthBias != 0.f;\r
649                         }\r
650 \r
651                         return false;\r
652                 }\r
653 \r
654                 //! Inequality operator\r
655                 /** \param b Material to compare to.\r
656                 \return True if the materials differ, else false. */\r
657                 inline bool operator!=(const SMaterial& b) const\r
658                 {\r
659                         bool different =\r
660                                 MaterialType != b.MaterialType ||\r
661                                 AmbientColor != b.AmbientColor ||\r
662                                 DiffuseColor != b.DiffuseColor ||\r
663                                 EmissiveColor != b.EmissiveColor ||\r
664                                 SpecularColor != b.SpecularColor ||\r
665                                 Shininess != b.Shininess ||\r
666                                 MaterialTypeParam != b.MaterialTypeParam ||\r
667                                 MaterialTypeParam2 != b.MaterialTypeParam2 ||\r
668                                 Thickness != b.Thickness ||\r
669                                 Wireframe != b.Wireframe ||\r
670                                 PointCloud != b.PointCloud ||\r
671                                 GouraudShading != b.GouraudShading ||\r
672                                 Lighting != b.Lighting ||\r
673                                 ZBuffer != b.ZBuffer ||\r
674                                 ZWriteEnable != b.ZWriteEnable ||\r
675                                 BackfaceCulling != b.BackfaceCulling ||\r
676                                 FrontfaceCulling != b.FrontfaceCulling ||\r
677                                 FogEnable != b.FogEnable ||\r
678                                 NormalizeNormals != b.NormalizeNormals ||\r
679                                 AntiAliasing != b.AntiAliasing ||\r
680                                 ColorMask != b.ColorMask ||\r
681                                 ColorMaterial != b.ColorMaterial ||\r
682                                 BlendOperation != b.BlendOperation ||\r
683                                 BlendFactor != b.BlendFactor ||\r
684                                 PolygonOffsetFactor != b.PolygonOffsetFactor ||\r
685                                 PolygonOffsetDirection != b.PolygonOffsetDirection ||\r
686                                 PolygonOffsetDepthBias != b.PolygonOffsetDepthBias ||\r
687                                 PolygonOffsetSlopeScale != b.PolygonOffsetSlopeScale ||\r
688                                 UseMipMaps != b.UseMipMaps\r
689                                 ;\r
690                         for (u32 i=0; (i<MATERIAL_MAX_TEXTURES) && !different; ++i)\r
691                         {\r
692                                 different |= (TextureLayer[i] != b.TextureLayer[i]);\r
693                         }\r
694                         return different;\r
695                 }\r
696 \r
697                 //! Equality operator\r
698                 /** \param b Material to compare to.\r
699                 \return True if the materials are equal, else false. */\r
700                 inline bool operator==(const SMaterial& b) const\r
701                 { return !(b!=*this); }\r
702 \r
703                 //! Check if material needs alpha blending\r
704                 bool isAlphaBlendOperation() const\r
705                 {\r
706                         if (BlendOperation != EBO_NONE && BlendFactor != 0.f)\r
707                         {\r
708                                 E_BLEND_FACTOR srcRGBFact = EBF_ZERO;\r
709                                 E_BLEND_FACTOR dstRGBFact = EBF_ZERO;\r
710                                 E_BLEND_FACTOR srcAlphaFact = EBF_ZERO;\r
711                                 E_BLEND_FACTOR dstAlphaFact = EBF_ZERO;\r
712                                 E_MODULATE_FUNC modulo = EMFN_MODULATE_1X;\r
713                                 u32 alphaSource = 0;\r
714 \r
715                                 unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulo, alphaSource, BlendFactor);\r
716 \r
717                                 if (textureBlendFunc_hasAlpha(srcRGBFact) || textureBlendFunc_hasAlpha(dstRGBFact) ||\r
718                                         textureBlendFunc_hasAlpha(srcAlphaFact) || textureBlendFunc_hasAlpha(dstAlphaFact))\r
719                                 {\r
720                                         return true;\r
721                                 }\r
722                         }\r
723                         return false;\r
724                 }\r
725 \r
726                 //! Check for some fixed-function transparent types. Still used internally, but might be deprecated soon.\r
727                 //! You probably should not use this anymore, IVideoDriver::needsTransparentRenderPass is more useful in most situations\r
728                 //! as it asks the material renders directly what they do with the material.\r
729                 bool isTransparent() const\r
730                 {\r
731                         if ( MaterialType==EMT_TRANSPARENT_ADD_COLOR ||\r
732                                 MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL ||\r
733                                 MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA ||\r
734                                 MaterialType==EMT_TRANSPARENT_REFLECTION_2_LAYER )\r
735                                 return true;\r
736 \r
737                         return false;\r
738                 }\r
739         };\r
740 \r
741         //! global const identity Material\r
742         IRRLICHT_API extern SMaterial IdentityMaterial;\r
743 } // end namespace video\r
744 } // end namespace irr\r
745 \r
746 #endif\r