////////////////////////////////////////////////////////////////////////////// // // Shader plug-ins // // Created: 8/18/98 Kells Elmquist // #ifndef SHADERS_H #define SHADERS_H #include "iparamb2.h" #include "stdmat.h" //#define STD2_NMAX_TEXMAPS 24 #define N_ID_CHANNELS 12 // number of ids in stdMat class Shader; #define OPACITY_PARAM 0 #define DEFAULT_SOFTEN 0.1f ///////////////////////////////////////////////////////////////////////////// // // Shader param dialog // // Returned by a shader when it is asked to put up its rollup page. class ShaderParamDlg : public ParamDlg { public: virtual Class_ID ClassID()=0; virtual void SetThing(ReferenceTarget *m)=0; virtual void SetThings( StdMat2* pMtl, Shader* pShader )=0; virtual ReferenceTarget* GetThing()=0; virtual Shader* GetShader()=0; virtual void SetTime(TimeValue t) {} virtual void DeleteThis()=0; virtual BOOL PanelProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam )=0; virtual void LoadDialog( int draw )=0; virtual void UpdateDialog( ParamID paramId )=0; virtual HWND GetHWnd()=0; virtual int FindSubTexFromHWND(HWND hw)=0; virtual void UpdateOpacity()=0; virtual void UpdateMapButtons()=0; }; ///////////////////////////////////sh flags ////////////////////////////////////// #define SELFILLUM_CLR_ON (1<<16) // can be or'd w/ mtl, not sure it's necessary /********* // post mapping params for shader class IllumParams { public: // these are the inputs to the shader, mostly textured channels ULONG mtlFlags; Shader* pShader; // for render elements to call the shader & mtl again, may be null Mtl* pMtl; // max mtl being shaded, null if bgnd // Point3 N, V; Color channels[ STD2_NMAX_TEXMAPS ]; float falloffOpac; // textured opacity w/ stdfalloff (reg opac in channels) float kR; // combined reflection.a * amt ULONG hasComponents; // bits for active components(e.g.currently has active refl map) ULONG stdParams; int* stdIDToChannel; // combined shader & mtl // these are the component-wise outputs from the shading process Color ambIllumOut, diffIllumOut, transIllumOut, selfIllumOut; // the diffuse clrs Color specIllumOut, reflIllumOut; // the specular colors // User Illumination outputs for render elements, name matched int nUserIllumOut; // one set of names for all illum params instances TCHAR** userIllumNames; // we just keep ptr to shared name array, not destroyed Color* userIllumOut; // the user illum color array, new'd & deleted w/ the class float diffIllumIntens; // used only by reflection dimming, intensity of diffIllum prior to color multiply float finalOpac; // for combining components // these are the outputs of the combiner Color finalC; // final clr: combiner composites into this value. Color finalT; // shader transp clr out public: // Illum params are allocated by materials during shading process to // communicate with shaders & render elements // So materials need to know how many userIllum slots they will use // most materials know this, but std2 will have to get it from the shader IllumParams( int nUserOut = 0, TCHAR** pUserNames = NULL ){ nUserIllumOut = nUserOut; userIllumOut = ( nUserOut )? new Color[ nUserOut ] : NULL; userIllumNames = pUserNames; } // IllumParams(){ // nUserIllumOut = 0; // userIllumOut = NULL; // userIllumNames = NULL; // } ~IllumParams(){ // We Dont destroy the name array as it's shared by all if( userIllumOut ) delete [] userIllumOut; } // returns number of user illum channels for this material int nUserIllumChannels(){ return nUserIllumOut; } // returns null if no name array specified TCHAR* GetUserIllumName( int n ) { DbgAssert( n < nUserIllumOut ); if( userIllumNames ) return userIllumNames[n]; return NULL; } // render elements, mtls & shaders can use this to find the index associated with a name // returns -1 if it can't find the name int FindUserIllumName( TCHAR* name ){ int n = -1; for( int i = 0; i < nUserIllumOut; ++i ){ DbgAssert( userIllumNames ); if( strcmp( name, userIllumNames[i] )){ n = i; break; } } return n; } // knowing the index, these set/get the user illum output color void SetUserIllumOutput( int n, Color& out ){ DbgAssert( n < nUserIllumOut ); userIllumOut[n] = out; } void SetUserIllumOutput( TCHAR* name, Color& out ){ for( int i = 0; i < nUserIllumOut; ++i ){ DbgAssert( userIllumNames ); if( strcmp( name, userIllumNames[i] )){ userIllumOut[i] = out; break; } } DbgAssert( i < nUserIllumOut ); } Color GetUserIllumOutput( int n ){ DbgAssert( n < nUserIllumOut ); return userIllumOut[n]; } Color GetUserIllumOutput( TCHAR* name, int n ){ for( int i = 0; i < nUserIllumOut; ++i ){ DbgAssert( userIllumNames ); if( strcmp( name, userIllumNames[i] )){ return userIllumOut[i]; } } return Color(0,0,0); } void ClearOutputs() { finalC = finalT = ambIllumOut=diffIllumOut=transIllumOut=selfIllumOut= specIllumOut=reflIllumOut= Color( 0.0f, 0.0f, 0.0f ); finalOpac = diffIllumIntens = 0.0f; for( int i=0; i < nUserIllumOut; ++i ) userIllumOut[i] = finalC; } void ClearInputs() { mtlFlags = stdParams = hasComponents = 0; pShader = NULL; pMtl = NULL; stdIDToChannel = NULL; kR = 0.0f; for( int i=0; i < STD2_NMAX_TEXMAPS; ++i ) channels[ i ] = Color( 0, 0, 0 ); } }; ********/ /////////// Components defines #define HAS_BUMPS 0x01L #define HAS_REFLECT 0x02L #define HAS_REFRACT 0x04L #define HAS_OPACITY 0x08L #define HAS_REFLECT_MAP 0x10L #define HAS_REFRACT_MAP 0x20L ////////// Texture channel type flags #define UNSUPPORTED_CHANNEL 0x01L #define CLR_CHANNEL 0x02L #define MONO_CHANNEL 0x04L #define BUMP_CHANNEL 0x08L #define REFL_CHANNEL 0x10L #define REFR_CHANNEL 0x20L #define DISP_CHANNEL 0x40L #define SLEV_CHANNEL 0x80L #define ELIMINATE_CHANNEL 0x8000L #define SKIP_CHANNELS (UNSUPPORTED_CHANNEL+BUMP_CHANNEL+REFL_CHANNEL+REFR_CHANNEL) /////////// Class Id upper half for loading the Pre 3.0 shaders #define DEFAULT_SHADER_CLASS_ID BLINNClassID #define PHONGClassID (STDSHADERS_CLASS_ID+2) #define BLINNClassID (STDSHADERS_CLASS_ID+3) #define METALClassID (STDSHADERS_CLASS_ID+4) class ParamBlockDescID; class IParamBlock; class BaseShader : public SpecialFX { public: RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message) {return REF_SUCCEED;} SClass_ID SuperClassID() {return SHADER_CLASS_ID;} BOOL BypassPropertyLevel() { return TRUE; } // want to promote shader props to material level virtual ULONG GetRequirements(int subMtlNum)=0; // Put up a dialog that lets the user edit the plug-ins parameters. virtual ShaderParamDlg* CreateParamDialog( HWND hOldRollup, HWND hwMtlEdit, IMtlParams *imp, StdMat2* theMtl, int rollupOpen, int n=0 )=0; virtual int NParamDlgs(){ return 1; } virtual ShaderParamDlg* GetParamDlg(int n=0 )=0; virtual void SetParamDlg( ShaderParamDlg* newDlg, int n=0 )=0; // Saves and loads name. These should be called at the start of // a plug-in's save and load methods. IOResult Save(ISave *isave) { return SpecialFX::Save(isave); } IOResult Load(ILoad *iload) { return SpecialFX::Load(iload); } // std parameter support virtual ULONG SupportStdParams()=0; // this method only req'd for R2.5 shaders, to convert stdmtl1 paramblks to current virtual void ConvertParamBlk( ParamBlockDescID *descOld, int oldCount, IParamBlock *oldPB ){}; // LOCAL vars of mtl for possible mapping prior to being given to back to illum virtual void GetIllumParams( ShadeContext &sc, IllumParams& ip )=0; // actual shader virtual void Illum(ShadeContext &sc, IllumParams &ip)=0; // begin - ke/mjm - 03.16.00 - merge reshading code // these support the pre-shade/reshade protocol // virtual void PreIllum(ShadeContext &sc, IReshadeFragment* pFrag){} // virtual void PostIllum(ShadeContext &sc, IllumParams &ip, IReshadeFragment* pFrag ){ Illum(sc,ip); } // >>>> new for V4, one call superceded, 2 new ones added virtual void ShadeReflection(ShadeContext &sc, IllumParams &ip, Color &mapClr){} virtual void ShadeTransmission(ShadeContext &sc, IllumParams &ip, Color &mapClr, float amount){} // orphaned, replaced by ShadeReflection() virtual void AffectReflection(ShadeContext &sc, IllumParams &ip, Color &rcol){} // end - ke/mjm - 03.16.00 - merge reshading code virtual void CombineComponents( ShadeContext &sc, IllumParams& ip ){}; // texture maps virtual long nTexChannelsSupported()=0; virtual TSTR GetTexChannelName( long nTextureChan )=0; virtual TSTR GetTexChannelInternalName( long nTextureChan ) { return GetTexChannelName(nTextureChan); } virtual long ChannelType( long nTextureChan )=0; // map StdMat Channel ID's to the channel number virtual long StdIDToChannel( long stdID )=0; // Shader Uses these UserIllum output channels virtual long nUserIllumOut(){ return 0; } // number of channels it will use // static name array for matching by render elements virtual TCHAR** UserIllumNameArray(){ return NULL; } // static name of each channel virtual void Reset()=0; //reset to default values }; // Chunk IDs saved by base class #define SHADERBASE_CHUNK 0x39bf #define SHADERNAME_CHUNK 0x0100 ///////////////////////////////////////////////////////////////////////////// // // Standard params for shaders // // combination of these is returned by Shader.SupportStdParams() #define STD_PARAM_NONE (0) #define STD_PARAM_ALL (0xffffffffL) #define STD_PARAM_METAL (1) #define STD_PARAM_LOCKDS (1<<1) #define STD_PARAM_LOCKAD (1<<2) #define STD_PARAM_LOCKADTEX (1<<3) #define STD_PARAM_SELFILLUM (1<<4) #define STD_PARAM_SELFILLUM_CLR (1<<5) #define STD_PARAM_AMBIENT_CLR (1<<6) #define STD_PARAM_DIFFUSE_CLR (1<<7) #define STD_PARAM_SPECULAR_CLR (1<<8) #define STD_PARAM_FILTER_CLR (1<<9) #define STD_PARAM_GLOSSINESS (1<<10) #define STD_PARAM_SOFTEN_LEV (1<<11) #define STD_PARAM_SPECULAR_LEV (1<<12) #define STD_PARAM_DIFFUSE_LEV (1<<13) #define STD_PARAM_DIFFUSE_RHO (1<<14) #define STD_PARAM_ANISO (1<<15) #define STD_PARAM_ORIENTATION (1<<16) #define STD_PARAM_REFL_LEV (1<<17) #define STD_PARAM_SELFILLUM_CLR_ON (1<<18) #define STD_BASIC2_DLG (1<<20) #define STD_EXTRA_DLG (1<<21) // not including these 3 in yr param string disables the relevant params // in extra params dialog #define STD_EXTRA_REFLECTION (1<<22) #define STD_EXTRA_REFRACTION (1<<23) #define STD_EXTRA_OPACITY (1<<24) #define STD_EXTRA (STD_EXTRA_DLG \ +STD_EXTRA_REFLECTION+STD_EXTRA_REFRACTION \ +STD_EXTRA_OPACITY ) #define STD_BASIC (0x00020ffeL | STD_BASIC2_DLG) #define STD_BASIC_METAL (0x00020fffL | STD_BASIC2_DLG) #define STD_ANISO (0x0002cffe) #define STD_MULTILAYER (0x0002fffe) #define STD_ONB (0x00023ffe) #define STD_WARD (0x00000bce) /////////////////////////////////////////////////////////////////////////////// class Shader : public BaseShader, public IReshading { public: virtual void CopyStdParams( Shader* pFrom )=0; // these are the standard shader params virtual void SetLockDS(BOOL lock)=0; virtual BOOL GetLockDS()=0; virtual void SetLockAD(BOOL lock)=0; virtual BOOL GetLockAD()=0; virtual void SetLockADTex(BOOL lock)=0; virtual BOOL GetLockADTex()=0; virtual void SetSelfIllum(float v, TimeValue t)=0; virtual void SetSelfIllumClrOn( BOOL on )=0; virtual void SetSelfIllumClr(Color c, TimeValue t)=0; virtual void SetAmbientClr(Color c, TimeValue t)=0; virtual void SetDiffuseClr(Color c, TimeValue t)=0; virtual void SetSpecularClr(Color c, TimeValue t)=0; virtual void SetGlossiness(float v, TimeValue t)=0; virtual void SetSpecularLevel(float v, TimeValue t)=0; virtual void SetSoftenLevel(float v, TimeValue t)=0; virtual BOOL IsSelfIllumClrOn(int mtlNum, BOOL backFace)=0; virtual Color GetAmbientClr(int mtlNum, BOOL backFace)=0; virtual Color GetDiffuseClr(int mtlNum, BOOL backFace)=0; virtual Color GetSpecularClr(int mtlNum, BOOL backFace)=0; virtual Color GetSelfIllumClr(int mtlNum, BOOL backFace)=0; virtual float GetSelfIllum(int mtlNum, BOOL backFace)=0; virtual float GetGlossiness(int mtlNum, BOOL backFace)=0; virtual float GetSpecularLevel(int mtlNum, BOOL backFace)=0; virtual float GetSoftenLevel(int mtlNum, BOOL backFace)=0; virtual BOOL IsSelfIllumClrOn()=0; virtual Color GetAmbientClr(TimeValue t)=0; virtual Color GetDiffuseClr(TimeValue t)=0; virtual Color GetSpecularClr(TimeValue t)=0; virtual float GetGlossiness( TimeValue t)=0; virtual float GetSpecularLevel(TimeValue t)=0; virtual float GetSoftenLevel(TimeValue t)=0; virtual float GetSelfIllum(TimeValue t)=0; virtual Color GetSelfIllumClr(TimeValue t)=0; virtual float EvalHiliteCurve(float x){ return 0.0f; } virtual float EvalHiliteCurve2(float x, float y, int level = 0 ){ return 0.0f; } // the Max std way of handling reflection and Transmission is // implemented here to provide the default implementation. CoreExport void ShadeReflection(ShadeContext &sc, IllumParams &ip, Color &mapClr); CoreExport void ShadeTransmission(ShadeContext &sc, IllumParams &ip, Color &mapClr, float amount); // Reshading void PreShade(ShadeContext& sc, IReshadeFragment* pFrag){} void PostShade(ShadeContext& sc, IReshadeFragment* pFrag, int& nextTexIndex, IllumParams* ip){ Illum( sc, *ip ); } void* GetInterface(ULONG id){ if( id == IID_IReshading ) return (IReshading*)( this ); // else if ( id == IID_IValidityToken ) // return (IValidityToken*)( this ); else return BaseShader::GetInterface(id); } }; #endif