Irrlicht 3D Engine
SMaterial.h
Go to the documentation of this file.
00001 // Copyright (C) 2002-2012 Nikolaus Gebhardt
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
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             // These pointers are checked during assignment
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             // Check for self-assignment!
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 } // end namespace video
00683 } // end namespace irr
00684 
00685 #endif