00001
00002
00003
00004
00005 #ifndef __S_MATERIAL_H_INCLUDED__
00006 #define __S_MATERIAL_H_INCLUDED__
00007
00008 #include "SColor.h"
00009 #include "matrix4.h"
00010 #include "irrArray.h"
00011 #include "irrMath.h"
00012 #include "EMaterialTypes.h"
00013 #include "EMaterialFlags.h"
00014 #include "SMaterialLayer.h"
00015
00016 namespace irr
00017 {
00018 namespace video
00019 {
00020 class ITexture;
00021
00023 enum E_BLEND_FACTOR
00024 {
00025 EBF_ZERO = 0,
00026 EBF_ONE,
00027 EBF_DST_COLOR,
00028 EBF_ONE_MINUS_DST_COLOR,
00029 EBF_SRC_COLOR,
00030 EBF_ONE_MINUS_SRC_COLOR,
00031 EBF_SRC_ALPHA,
00032 EBF_ONE_MINUS_SRC_ALPHA,
00033 EBF_DST_ALPHA,
00034 EBF_ONE_MINUS_DST_ALPHA,
00035 EBF_SRC_ALPHA_SATURATE
00036 };
00037
00039 enum E_BLEND_OPERATION
00040 {
00041 EBO_NONE = 0,
00042 EBO_ADD,
00043 EBO_SUBTRACT,
00044 EBO_REVSUBTRACT,
00045 EBO_MIN,
00046 EBO_MAX,
00047 EBO_MIN_FACTOR,
00048 EBO_MAX_FACTOR,
00049 EBO_MIN_ALPHA,
00050 EBO_MAX_ALPHA
00051 };
00052
00054 enum E_MODULATE_FUNC
00055 {
00056 EMFN_MODULATE_1X = 1,
00057 EMFN_MODULATE_2X = 2,
00058 EMFN_MODULATE_4X = 4
00059 };
00060
00062 enum E_COMPARISON_FUNC
00063 {
00065 ECFN_NEVER=0,
00067 ECFN_LESSEQUAL=1,
00069 ECFN_EQUAL=2,
00071 ECFN_LESS,
00073 ECFN_NOTEQUAL,
00075 ECFN_GREATEREQUAL,
00077 ECFN_GREATER,
00079 ECFN_ALWAYS
00080 };
00081
00083 enum E_COLOR_PLANE
00084 {
00086 ECP_NONE=0,
00088 ECP_ALPHA=1,
00090 ECP_RED=2,
00092 ECP_GREEN=4,
00094 ECP_BLUE=8,
00096 ECP_RGB=14,
00098 ECP_ALL=15
00099 };
00100
00102
00104 enum E_ALPHA_SOURCE
00105 {
00107 EAS_NONE=0,
00109 EAS_VERTEX_COLOR,
00111 EAS_TEXTURE
00112 };
00113
00115
00116 inline f32 pack_textureBlendFunc ( const E_BLEND_FACTOR srcFact, const E_BLEND_FACTOR dstFact, const E_MODULATE_FUNC modulate=EMFN_MODULATE_1X, const u32 alphaSource=EAS_TEXTURE )
00117 {
00118 const u32 tmp = (alphaSource << 12) | (modulate << 8) | (srcFact << 4) | dstFact;
00119 return FR(tmp);
00120 }
00121
00123
00124 inline void unpack_textureBlendFunc ( E_BLEND_FACTOR &srcFact, E_BLEND_FACTOR &dstFact,
00125 E_MODULATE_FUNC &modulo, u32& alphaSource, const f32 param )
00126 {
00127 const u32 state = IR(param);
00128 alphaSource = (state & 0x0000F000) >> 12;
00129 modulo = E_MODULATE_FUNC( ( state & 0x00000F00 ) >> 8 );
00130 srcFact = E_BLEND_FACTOR ( ( state & 0x000000F0 ) >> 4 );
00131 dstFact = E_BLEND_FACTOR ( ( state & 0x0000000F ) );
00132 }
00133
00135 inline bool textureBlendFunc_hasAlpha ( const E_BLEND_FACTOR factor )
00136 {
00137 switch ( factor )
00138 {
00139 case EBF_SRC_ALPHA:
00140 case EBF_ONE_MINUS_SRC_ALPHA:
00141 case EBF_DST_ALPHA:
00142 case EBF_ONE_MINUS_DST_ALPHA:
00143 case EBF_SRC_ALPHA_SATURATE:
00144 return true;
00145 default:
00146 return false;
00147 }
00148 }
00149
00150
00152
00158 enum E_ANTI_ALIASING_MODE
00159 {
00161 EAAM_OFF=0,
00163 EAAM_SIMPLE=1,
00165 EAAM_QUALITY=3,
00167 EAAM_LINE_SMOOTH=4,
00169 EAAM_POINT_SMOOTH=8,
00171 EAAM_FULL_BASIC=15,
00173
00174 EAAM_ALPHA_TO_COVERAGE=16
00175 };
00176
00178
00184 enum E_COLOR_MATERIAL
00185 {
00187 ECM_NONE=0,
00189 ECM_DIFFUSE,
00191 ECM_AMBIENT,
00193 ECM_EMISSIVE,
00195 ECM_SPECULAR,
00197 ECM_DIFFUSE_AND_AMBIENT
00198 };
00199
00201
00202 enum E_POLYGON_OFFSET
00203 {
00205
00206 EPO_BACK=0,
00208
00210 EPO_FRONT=1
00211 };
00212
00214 const c8* const PolygonOffsetDirectionNames[] =
00215 {
00216 "Back",
00217 "Front",
00218 0
00219 };
00220
00221
00223 const u32 MATERIAL_MAX_TEXTURES = _IRR_MATERIAL_MAX_TEXTURES_;
00224
00226 class SMaterial
00227 {
00228 public:
00230 SMaterial()
00231 : MaterialType(EMT_SOLID), AmbientColor(255,255,255,255), DiffuseColor(255,255,255,255),
00232 EmissiveColor(0,0,0,0), SpecularColor(255,255,255,255),
00233 Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f),
00234 ZBuffer(ECFN_LESSEQUAL), AntiAliasing(EAAM_SIMPLE), ColorMask(ECP_ALL),
00235 ColorMaterial(ECM_DIFFUSE), BlendOperation(EBO_NONE),
00236 PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT),
00237 Wireframe(false), PointCloud(false), GouraudShading(true),
00238 Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false),
00239 FogEnable(false), NormalizeNormals(false), UseMipMaps(true)
00240 { }
00241
00243
00244 SMaterial(const SMaterial& other)
00245 {
00246
00247 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
00248 TextureLayer[i].TextureMatrix = 0;
00249 *this = other;
00250 }
00251
00253
00254 SMaterial& operator=(const SMaterial& other)
00255 {
00256
00257 if (this == &other)
00258 return *this;
00259
00260 MaterialType = other.MaterialType;
00261
00262 AmbientColor = other.AmbientColor;
00263 DiffuseColor = other.DiffuseColor;
00264 EmissiveColor = other.EmissiveColor;
00265 SpecularColor = other.SpecularColor;
00266 Shininess = other.Shininess;
00267 MaterialTypeParam = other.MaterialTypeParam;
00268 MaterialTypeParam2 = other.MaterialTypeParam2;
00269 Thickness = other.Thickness;
00270 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
00271 {
00272 TextureLayer[i] = other.TextureLayer[i];
00273 }
00274
00275 Wireframe = other.Wireframe;
00276 PointCloud = other.PointCloud;
00277 GouraudShading = other.GouraudShading;
00278 Lighting = other.Lighting;
00279 ZWriteEnable = other.ZWriteEnable;
00280 BackfaceCulling = other.BackfaceCulling;
00281 FrontfaceCulling = other.FrontfaceCulling;
00282 FogEnable = other.FogEnable;
00283 NormalizeNormals = other.NormalizeNormals;
00284 ZBuffer = other.ZBuffer;
00285 AntiAliasing = other.AntiAliasing;
00286 ColorMask = other.ColorMask;
00287 ColorMaterial = other.ColorMaterial;
00288 BlendOperation = other.BlendOperation;
00289 PolygonOffsetFactor = other.PolygonOffsetFactor;
00290 PolygonOffsetDirection = other.PolygonOffsetDirection;
00291 UseMipMaps = other.UseMipMaps;
00292
00293 return *this;
00294 }
00295
00297 SMaterialLayer TextureLayer[MATERIAL_MAX_TEXTURES];
00298
00300 E_MATERIAL_TYPE MaterialType;
00301
00303
00306 SColor AmbientColor;
00307
00309
00310 SColor DiffuseColor;
00311
00313 SColor EmissiveColor;
00314
00316
00318 SColor SpecularColor;
00319
00321
00350 f32 Shininess;
00351
00353
00355 f32 MaterialTypeParam;
00356
00358
00359 f32 MaterialTypeParam2;
00360
00362 f32 Thickness;
00363
00365
00366 u8 ZBuffer;
00367
00369
00372 u8 AntiAliasing;
00373
00375
00379 u8 ColorMask:4;
00380
00382
00387 u8 ColorMaterial:3;
00388
00390
00392 E_BLEND_OPERATION BlendOperation:4;
00393
00395
00397 u8 PolygonOffsetFactor:3;
00398
00400
00401 E_POLYGON_OFFSET PolygonOffsetDirection:1;
00402
00404
00407 bool Wireframe:1;
00408
00410 bool PointCloud:1;
00411
00413 bool GouraudShading:1;
00414
00416 bool Lighting:1;
00417
00419
00422 bool ZWriteEnable:1;
00423
00425 bool BackfaceCulling:1;
00426
00428 bool FrontfaceCulling:1;
00429
00431 bool FogEnable:1;
00432
00434
00435 bool NormalizeNormals:1;
00436
00438
00439 bool UseMipMaps:1;
00440
00442
00444 core::matrix4& getTextureMatrix(u32 i)
00445 {
00446 return TextureLayer[i].getTextureMatrix();
00447 }
00448
00450
00452 const core::matrix4& getTextureMatrix(u32 i) const
00453 {
00454 if (i<MATERIAL_MAX_TEXTURES)
00455 return TextureLayer[i].getTextureMatrix();
00456 else
00457 return core::IdentityMatrix;
00458 }
00459
00461
00463 void setTextureMatrix(u32 i, const core::matrix4& mat)
00464 {
00465 if (i>=MATERIAL_MAX_TEXTURES)
00466 return;
00467 TextureLayer[i].setTextureMatrix(mat);
00468 }
00469
00471
00473 ITexture* getTexture(u32 i) const
00474 {
00475 return i < MATERIAL_MAX_TEXTURES ? TextureLayer[i].Texture : 0;
00476 }
00477
00479
00482 void setTexture(u32 i, ITexture* tex)
00483 {
00484 if (i>=MATERIAL_MAX_TEXTURES)
00485 return;
00486 TextureLayer[i].Texture = tex;
00487 }
00488
00490
00492 void setFlag(E_MATERIAL_FLAG flag, bool value)
00493 {
00494 switch (flag)
00495 {
00496 case EMF_WIREFRAME:
00497 Wireframe = value; break;
00498 case EMF_POINTCLOUD:
00499 PointCloud = value; break;
00500 case EMF_GOURAUD_SHADING:
00501 GouraudShading = value; break;
00502 case EMF_LIGHTING:
00503 Lighting = value; break;
00504 case EMF_ZBUFFER:
00505 ZBuffer = value; break;
00506 case EMF_ZWRITE_ENABLE:
00507 ZWriteEnable = value; break;
00508 case EMF_BACK_FACE_CULLING:
00509 BackfaceCulling = value; break;
00510 case EMF_FRONT_FACE_CULLING:
00511 FrontfaceCulling = value; break;
00512 case EMF_BILINEAR_FILTER:
00513 {
00514 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
00515 TextureLayer[i].BilinearFilter = value;
00516 }
00517 break;
00518 case EMF_TRILINEAR_FILTER:
00519 {
00520 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
00521 TextureLayer[i].TrilinearFilter = value;
00522 }
00523 break;
00524 case EMF_ANISOTROPIC_FILTER:
00525 {
00526 if (value)
00527 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
00528 TextureLayer[i].AnisotropicFilter = 0xFF;
00529 else
00530 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
00531 TextureLayer[i].AnisotropicFilter = 0;
00532 }
00533 break;
00534 case EMF_FOG_ENABLE:
00535 FogEnable = value; break;
00536 case EMF_NORMALIZE_NORMALS:
00537 NormalizeNormals = value; break;
00538 case EMF_TEXTURE_WRAP:
00539 {
00540 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
00541 {
00542 TextureLayer[i].TextureWrapU = (E_TEXTURE_CLAMP)value;
00543 TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)value;
00544 }
00545 }
00546 break;
00547 case EMF_ANTI_ALIASING:
00548 AntiAliasing = value?EAAM_SIMPLE:EAAM_OFF; break;
00549 case EMF_COLOR_MASK:
00550 ColorMask = value?ECP_ALL:ECP_NONE; break;
00551 case EMF_COLOR_MATERIAL:
00552 ColorMaterial = value?ECM_DIFFUSE:ECM_NONE; break;
00553 case EMF_USE_MIP_MAPS:
00554 UseMipMaps = value; break;
00555 case EMF_BLEND_OPERATION:
00556 BlendOperation = value?EBO_ADD:EBO_NONE; break;
00557 case EMF_POLYGON_OFFSET:
00558 PolygonOffsetFactor = value?1:0;
00559 PolygonOffsetDirection = EPO_BACK;
00560 break;
00561 default:
00562 break;
00563 }
00564 }
00565
00567
00569 bool getFlag(E_MATERIAL_FLAG flag) const
00570 {
00571 switch (flag)
00572 {
00573 case EMF_WIREFRAME:
00574 return Wireframe;
00575 case EMF_POINTCLOUD:
00576 return PointCloud;
00577 case EMF_GOURAUD_SHADING:
00578 return GouraudShading;
00579 case EMF_LIGHTING:
00580 return Lighting;
00581 case EMF_ZBUFFER:
00582 return ZBuffer!=ECFN_NEVER;
00583 case EMF_ZWRITE_ENABLE:
00584 return ZWriteEnable;
00585 case EMF_BACK_FACE_CULLING:
00586 return BackfaceCulling;
00587 case EMF_FRONT_FACE_CULLING:
00588 return FrontfaceCulling;
00589 case EMF_BILINEAR_FILTER:
00590 return TextureLayer[0].BilinearFilter;
00591 case EMF_TRILINEAR_FILTER:
00592 return TextureLayer[0].TrilinearFilter;
00593 case EMF_ANISOTROPIC_FILTER:
00594 return TextureLayer[0].AnisotropicFilter!=0;
00595 case EMF_FOG_ENABLE:
00596 return FogEnable;
00597 case EMF_NORMALIZE_NORMALS:
00598 return NormalizeNormals;
00599 case EMF_TEXTURE_WRAP:
00600 return !(TextureLayer[0].TextureWrapU ||
00601 TextureLayer[0].TextureWrapV ||
00602 TextureLayer[1].TextureWrapU ||
00603 TextureLayer[1].TextureWrapV ||
00604 TextureLayer[2].TextureWrapU ||
00605 TextureLayer[2].TextureWrapV ||
00606 TextureLayer[3].TextureWrapU ||
00607 TextureLayer[3].TextureWrapV);
00608 case EMF_ANTI_ALIASING:
00609 return (AntiAliasing==1);
00610 case EMF_COLOR_MASK:
00611 return (ColorMask!=ECP_NONE);
00612 case EMF_COLOR_MATERIAL:
00613 return (ColorMaterial != ECM_NONE);
00614 case EMF_USE_MIP_MAPS:
00615 return UseMipMaps;
00616 case EMF_BLEND_OPERATION:
00617 return BlendOperation != EBO_NONE;
00618 case EMF_POLYGON_OFFSET:
00619 return PolygonOffsetFactor != 0;
00620 }
00621
00622 return false;
00623 }
00624
00626
00628 inline bool operator!=(const SMaterial& b) const
00629 {
00630 bool different =
00631 MaterialType != b.MaterialType ||
00632 AmbientColor != b.AmbientColor ||
00633 DiffuseColor != b.DiffuseColor ||
00634 EmissiveColor != b.EmissiveColor ||
00635 SpecularColor != b.SpecularColor ||
00636 Shininess != b.Shininess ||
00637 MaterialTypeParam != b.MaterialTypeParam ||
00638 MaterialTypeParam2 != b.MaterialTypeParam2 ||
00639 Thickness != b.Thickness ||
00640 Wireframe != b.Wireframe ||
00641 PointCloud != b.PointCloud ||
00642 GouraudShading != b.GouraudShading ||
00643 Lighting != b.Lighting ||
00644 ZBuffer != b.ZBuffer ||
00645 ZWriteEnable != b.ZWriteEnable ||
00646 BackfaceCulling != b.BackfaceCulling ||
00647 FrontfaceCulling != b.FrontfaceCulling ||
00648 FogEnable != b.FogEnable ||
00649 NormalizeNormals != b.NormalizeNormals ||
00650 AntiAliasing != b.AntiAliasing ||
00651 ColorMask != b.ColorMask ||
00652 ColorMaterial != b.ColorMaterial ||
00653 BlendOperation != b.BlendOperation ||
00654 PolygonOffsetFactor != b.PolygonOffsetFactor ||
00655 PolygonOffsetDirection != b.PolygonOffsetDirection ||
00656 UseMipMaps != b.UseMipMaps;
00657 for (u32 i=0; (i<MATERIAL_MAX_TEXTURES) && !different; ++i)
00658 {
00659 different |= (TextureLayer[i] != b.TextureLayer[i]);
00660 }
00661 return different;
00662 }
00663
00665
00667 inline bool operator==(const SMaterial& b) const
00668 { return !(b!=*this); }
00669
00670 bool isTransparent() const
00671 {
00672 return MaterialType==EMT_TRANSPARENT_ADD_COLOR ||
00673 MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL ||
00674 MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA ||
00675 MaterialType==EMT_TRANSPARENT_REFLECTION_2_LAYER;
00676 }
00677 };
00678
00680 IRRLICHT_API extern SMaterial IdentityMaterial;
00681
00682 }
00683 }
00684
00685 #endif