00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_MATERIAL_H
00027 #define NL_MATERIAL_H
00028
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/smart_ptr.h"
00031 #include "nel/misc/rgba.h"
00032 #include "nel/misc/matrix.h"
00033 #include "3d/texture.h"
00034 #include "3d/shader.h"
00035
00036 #include <memory>
00037
00038 namespace NL3D {
00039
00040 using NLMISC::CRefCount;
00041 using NLMISC::CRGBA;
00042 using NLMISC::CSmartPtr;
00043 using NLMISC::CRefPtr;
00044
00045
00046
00047 const uint32 IDRV_MAT_MAXTEXTURES = 4;
00048
00049 const uint32 IDRV_TOUCHED_BLENDFUNC = 0x00000001;
00050 const uint32 IDRV_TOUCHED_BLEND = 0x00000002;
00051 const uint32 IDRV_TOUCHED_SHADER = 0x00000004;
00052 const uint32 IDRV_TOUCHED_ZFUNC = 0x00000008;
00053 const uint32 IDRV_TOUCHED_ZBIAS = 0x00000010;
00054 const uint32 IDRV_TOUCHED_COLOR = 0x00000020;
00055 const uint32 IDRV_TOUCHED_LIGHTING = 0x00000040;
00056 const uint32 IDRV_TOUCHED_DEFMAT = 0x00000080;
00057 const uint32 IDRV_TOUCHED_ZWRITE = 0x00000100;
00058 const uint32 IDRV_TOUCHED_DOUBLE_SIDED = 0x00000200;
00059 const uint32 IDRV_TOUCHED_LIGHTMAP = 0x00000400;
00060 const uint32 IDRV_TOUCHED_ALPHA_TEST = 0x00000800;
00061 const uint32 IDRV_TOUCHED_ALPHA_TEST_THRE = 0x00001000;
00062
00063
00064
00065 const uint32 IDRV_TOUCHED_TEX[IDRV_MAT_MAXTEXTURES] =
00066 {0x00010000, 0x00020000, 0x00040000, 0x00080000};
00067 const uint32 IDRV_TOUCHED_ALL = 0xFFFFFFFF;
00068
00069
00070 const uint32 IDRV_MAT_HIDE = 0x00000001;
00071 const uint32 IDRV_MAT_TSP = 0x00000002;
00072 const uint32 IDRV_MAT_ZWRITE = 0x00000004;
00073 const uint32 IDRV_MAT_ZLIST = 0x00000008;
00074 const uint32 IDRV_MAT_LIGHTING = 0x00000010;
00075 const uint32 IDRV_MAT_SPECULAR = 0x00000020;
00076 const uint32 IDRV_MAT_DEFMAT = 0x00000040;
00077 const uint32 IDRV_MAT_BLEND = 0x00000080;
00078 const uint32 IDRV_MAT_DOUBLE_SIDED = 0x00000100;
00079 const uint32 IDRV_MAT_ALPHA_TEST = 0x00000200;
00080 const uint32 IDRV_MAT_TEX_ADDR = 0x00000400;
00081 const uint32 IDRV_MAT_LIGHTED_VERTEX_COLOR = 0x00000800;
00083 const uint32 IDRV_MAT_GEN_TEX_0 = 0x00001000;
00084 const uint32 IDRV_MAT_GEN_TEX_1 = 0x00002000;
00085 const uint32 IDRV_MAT_GEN_TEX_2 = 0x00004000;
00086 const uint32 IDRV_MAT_GEN_TEX_3 = 0x00008000;
00087 const uint32 IDRV_MAT_GEN_TEX_4 = 0x00010000;
00088 const uint32 IDRV_MAT_GEN_TEX_5 = 0x00020000;
00089 const uint32 IDRV_MAT_GEN_TEX_6 = 0x00040000;
00090 const uint32 IDRV_MAT_GEN_TEX_7 = 0x00080000;
00092 const uint32 IDRV_MAT_USER_TEX_0_MAT = 0x00100000;
00093 const uint32 IDRV_MAT_USER_TEX_1_MAT = 0x00200000;
00094 const uint32 IDRV_MAT_USER_TEX_2_MAT = 0x00400000;
00095 const uint32 IDRV_MAT_USER_TEX_3_MAT = 0x00800000;
00096 const uint32 IDRV_MAT_USER_TEX_4_MAT = 0x01000000;
00097 const uint32 IDRV_MAT_USER_TEX_5_MAT = 0x02000000;
00098 const uint32 IDRV_MAT_USER_TEX_6_MAT = 0x04000000;
00099 const uint32 IDRV_MAT_USER_TEX_7_MAT = 0x08000000;
00100 const uint32 IDRV_MAT_USER_TEX_MAT_ALL = 0x0FF00000;
00101
00102 const uint32 IDRV_MAT_USER_TEX_FIRST_BIT = 20;
00103
00104
00105
00106
00111
00112
00113
00114
00115 class CMaterial : public CRefCount
00116 {
00117 public:
00118
00119 enum ZFunc { always=0,never,equal,notequal,less,lessequal,greater,greaterequal, zfuncCount };
00120
00125 enum TBlend { one=0, zero, srcalpha, invsrcalpha, srccolor, invsrccolor,
00126 blendConstantColor, blendConstantInvColor, blendConstantAlpha, blendConstantInvAlpha, blendCount };
00127
00157 enum TShader { Normal=0,
00158 Bump,
00159 UserColor,
00160 LightMap,
00161 Specular,
00162 Caustics,
00163 PerPixelLighting,
00164 PerPixelLightingNoSpec,
00165 Cloud,
00166 shaderCount};
00167
00169
00181 enum TTexOperator { Replace=0, Modulate, Add, AddSigned,
00182 InterpolateTexture, InterpolatePrevious, InterpolateDiffuse, InterpolateConstant, EMBM };
00183
00190 enum TTexSource { Texture=0, Previous, Diffuse, Constant };
00191
00199 enum TTexOperand { SrcColor=0, InvSrcColor, SrcAlpha, InvSrcAlpha };
00200
00201
00207
00208 enum TTexAddressingMode {
00209 TextureOff = 0 , FetchTexture, PassThrough, CullFragment,
00210 OffsetTexture, OffsetTextureScale,
00211 DependentARTexture, DependentGBTexture,
00212 DP3, DP3Texture2D,
00213 DP3CubeMap, DP3ReflectCubeMap, DP3ConstEyeReflectCubeMap,
00214 DP3DiffuseCubeMap,
00215 DP3DepthReplace,
00216 TexAddrCount
00217 };
00218
00219
00220
00221 public:
00223
00228 CMaterial();
00230 CMaterial(const CMaterial &mat) {_Touched= 0;_Flags=0; operator=(mat);}
00232 ~CMaterial();
00234 CMaterial &operator=(const CMaterial &mat);
00235
00236
00240 void setShader(TShader val);
00242 TShader getShader() const {return _ShaderType;}
00243
00245
00252 void setTexture(uint8 stage, ITexture* ptex);
00253
00254 ITexture* getTexture(uint8 stage) const;
00255 bool texturePresent(uint8 stage) const;
00256
00257
00258
00260
00261 void setBlend(bool active);
00262 void setBlendFunc(TBlend src, TBlend dst);
00263 void setSrcBlend(TBlend val);
00264 void setDstBlend(TBlend val);
00265
00266 bool getBlend() const { return (_Flags&IDRV_MAT_BLEND)!=0; }
00267 TBlend getSrcBlend(void) const { return(_SrcBlend); }
00268 TBlend getDstBlend(void) const { return(_DstBlend); }
00269
00270
00271
00273
00277 void enableTexAddrMode(bool enable = true);
00278
00280 bool texAddrEnabled() const;
00281
00286 void setTexAddressingMode(uint8 stage, TTexAddressingMode mode);
00287
00289 TTexAddressingMode getTexAddressingMode(uint8 stage);
00290
00291
00292
00294
00295 void setDoubleSided(bool active);
00296 bool getDoubleSided() const { return (_Flags&IDRV_MAT_DOUBLE_SIDED)!=0; }
00297
00298
00300
00301 void setAlphaTest(bool active);
00302 bool getAlphaTest() const { return (_Flags&IDRV_MAT_ALPHA_TEST)!=0; }
00303
00307 void setAlphaTestThreshold(float thre);
00308 float getAlphaTestThreshold() const { return _AlphaTestThreshold; }
00309
00310
00311
00312
00314
00315 void setZFunc(ZFunc val);
00316 void setZWrite(bool active);
00317
00320 void setZBias(float val);
00321
00322 ZFunc getZFunc(void) const { return(_ZFunction); }
00323 bool getZWrite(void) const{ return (_Flags&IDRV_MAT_ZWRITE)!=0; }
00324 float getZBias(void) const { return(_ZBias); }
00325
00326
00327
00329
00331
00332
00334 void setLighting( bool active,
00335 CRGBA emissive=CRGBA(0,0,0),
00336 CRGBA ambient=CRGBA(0,0,0),
00337 CRGBA diffuse=CRGBA(0,0,0),
00338 CRGBA specular=CRGBA(0,0,0),
00339 float shininess= 10);
00340
00342 void setEmissive( CRGBA emissive=CRGBA(0,0,0) );
00344 void setAmbient( CRGBA ambient=CRGBA(0,0,0) );
00346 void setDiffuse( CRGBA diffuse=CRGBA(0,0,0) );
00348 void setOpacity( uint8 opa );
00350 void setSpecular( CRGBA specular=CRGBA(0,0,0) );
00352 void setShininess( float shininess );
00354 void setLightedVertexColor (bool useLightedVertexColor);
00356 bool getLightedVertexColor () const;
00357
00358
00359 bool isLighted() const {return (_Flags&IDRV_MAT_LIGHTING)!=0;}
00360
00362 bool isLightedVertexColor () const { return (_Flags&IDRV_MAT_LIGHTED_VERTEX_COLOR)!=0;}
00363
00364 CRGBA getColor(void) const { return(_Color); }
00365 CRGBA getEmissive() const { return _Emissive;}
00366 CRGBA getAmbient() const { return _Ambient;}
00368 CRGBA getDiffuse() const { return _Diffuse;}
00369 uint8 getOpacity() const { return _Diffuse.A;}
00370 CRGBA getSpecular() const { return _Specular;}
00371 float getShininess() const { return _Shininess;}
00372
00373
00374
00376
00387
00388 void texEnvOpRGB(uint stage, TTexOperator ope);
00389 void texEnvArg0RGB(uint stage, TTexSource src, TTexOperand oper);
00390 void texEnvArg1RGB(uint stage, TTexSource src, TTexOperand oper);
00391 void texEnvOpAlpha(uint stage, TTexOperator ope);
00392 void texEnvArg0Alpha(uint stage, TTexSource src, TTexOperand oper);
00393 void texEnvArg1Alpha(uint stage, TTexSource src, TTexOperand oper);
00395 void texConstantColor(uint stage, CRGBA color);
00397 uint32 getTexEnvMode(uint stage);
00399 void setTexEnvMode(uint stage, uint32 packed);
00400 CRGBA getTexConstantColor(uint stage);
00401
00402 void setTexCoordGen(uint stage, bool generate);
00403 bool getTexCoordGen(uint stage) const;
00404
00405
00406 void enableUserTexMat(uint stage, bool enabled = true);
00407
00408 bool isUserTexMatEnabled(uint stage) const;
00410 void setUserTexMat(uint stage, const NLMISC::CMatrix &m);
00414 const NLMISC::CMatrix &getUserTexMat(uint stage) const;
00416 void decompUserTexMat(uint stage, float &uTrans, float &vTrans, float &wRot, float &uScale, float &vScale);
00417
00418
00419
00420
00422
00425
00426 void setUserColor(CRGBA userColor);
00427 CRGBA getUserColor() const;
00428
00429
00431
00434
00436
00438
00440
00441
00442
00443
00445
00450 void initUnlit();
00455 void initLighted();
00456
00457
00458
00459 bool getStainedGlassWindow() { return _StainedGlassWindow; }
00460 void setStainedGlassWindow(bool val) { _StainedGlassWindow = val; }
00461
00463 void flushTextures (IDriver &driver);
00464
00465 void serial(NLMISC::IStream &f);
00466
00467
00468
00472 void selectTextureSet(uint index);
00473
00474
00475
00476
00477 public:
00478
00479 struct CTexEnv
00480 {
00481 union
00482 {
00483 uint32 EnvPacked;
00484 struct
00485 {
00486 uint32 OpRGB:4;
00487 uint32 SrcArg0RGB:2;
00488 uint32 OpArg0RGB:2;
00489 uint32 SrcArg1RGB:2;
00490 uint32 OpArg1RGB:2;
00491
00492 uint32 OpAlpha:4;
00493 uint32 SrcArg0Alpha:2;
00494 uint32 OpArg0Alpha:2;
00495 uint32 SrcArg1Alpha:2;
00496 uint32 OpArg1Alpha:2;
00497 } Env;
00498 };
00499 CRGBA ConstantColor;
00500
00501 void setDefault()
00502 {
00503
00504
00505
00506 Env.OpRGB= Modulate;
00507 Env.SrcArg0RGB= Texture;
00508 Env.OpArg0RGB= SrcColor;
00509 Env.SrcArg1RGB= Previous;
00510 Env.OpArg1RGB= SrcColor;
00511
00512 Env.OpAlpha= Modulate;
00513 Env.SrcArg0Alpha= Texture;
00514 Env.OpArg0Alpha= SrcAlpha;
00515 Env.SrcArg1Alpha= Previous;
00516 Env.OpArg1Alpha= SrcAlpha;
00517
00518 ConstantColor.set(255,255,255,255);
00519 }
00520
00521 void serial(NLMISC::IStream &f)
00522 {
00523 Env.OpRGB= f.serialBitField8(Env.OpRGB);
00524 Env.SrcArg0RGB= f.serialBitField8(Env.SrcArg0RGB);
00525 Env.OpArg0RGB= f.serialBitField8(Env.OpArg0RGB);
00526 Env.SrcArg1RGB= f.serialBitField8(Env.SrcArg1RGB);
00527 Env.OpArg1RGB= f.serialBitField8(Env.OpArg1RGB);
00528
00529 Env.OpAlpha= f.serialBitField8(Env.OpAlpha);
00530 Env.SrcArg0Alpha= f.serialBitField8(Env.SrcArg0Alpha);
00531 Env.OpArg0Alpha= f.serialBitField8(Env.OpArg0Alpha);
00532 Env.SrcArg1Alpha= f.serialBitField8(Env.SrcArg1Alpha);
00533 Env.OpArg1Alpha= f.serialBitField8(Env.OpArg1Alpha);
00534
00535 f.serial(ConstantColor);
00536 }
00537
00538
00539 CTexEnv()
00540 {
00541 setDefault();
00542 }
00543 };
00544
00545 private:
00546
00547 TShader _ShaderType;
00548 uint32 _Flags;
00549 TBlend _SrcBlend,_DstBlend;
00550 ZFunc _ZFunction;
00551 float _ZBias;
00552 CRGBA _Color;
00553 CRGBA _Emissive, _Ambient, _Diffuse, _Specular;
00554 float _Shininess;
00555 float _AlphaTestThreshold;
00556 uint32 _Touched;
00557 bool _StainedGlassWindow;
00558 struct CUserTexMat
00559 {
00560 NLMISC::CMatrix TexMat[IDRV_MAT_MAXTEXTURES];
00561 };
00562 std::auto_ptr<CUserTexMat> _TexUserMat;
00563 CSmartPtr<ITexture> _Textures[IDRV_MAT_MAXTEXTURES];
00564
00565 public:
00566
00567 uint8 _TexAddrMode[IDRV_MAT_MAXTEXTURES];
00568 CTexEnv _TexEnvs[IDRV_MAT_MAXTEXTURES];
00569 CRefPtr<IShader> pShader;
00570
00571
00572 struct CLightMap
00573 {
00574 CSmartPtr<ITexture> Texture;
00575 CRGBA Factor;
00576 CLightMap()
00577 {
00578 Factor.set(255, 255, 255, 255);
00579 }
00580
00581 void serial(NLMISC::IStream &f);
00582 };
00583 typedef std::vector<CLightMap> TTexturePtrs;
00584 TTexturePtrs _LightMaps;
00585
00586
00587 uint32 getFlags() const {return _Flags;}
00588 uint32 getTouched(void) const { return(_Touched); }
00589 void clearTouched(uint32 flag) { _Touched&=~flag; }
00590
00591
00592
00593 };
00594
00595 }
00596
00597 #include "3d/driver_material_inline.h"
00598
00599 #endif // NL_MATERIAL_H
00600
00601