1 ///////////////////////////////////////////////////////////////////
2 //
3 // MultiLayer shader
4 //
5 // Created: 11/23/98 Kells Elmquist
6 //
7 #include "shadersPch.h"
8 #include "shadersRc.h"
9 #include "gport.h"
10 #include "shaders.h"
11 #include "shaderUtil.h"
12 #include "macrorec.h"
13 #include "toneop.h"
14
15 #include "3dsmaxport.h"
16
17 // Class Ids
18 #define MULTILAYERSHADER_CLASS_ID 0x2857f470
19
20 static Class_ID MultiLayerShaderClassID( MULTILAYERSHADER_CLASS_ID, 0);
21
22
23 // paramblock2 block and parameter IDs.
24 enum { multiLayer_params, };
25 // shdr_params param IDs
26 enum
27 {
28 ml_ambient, ml_diffuse, ml_self_illum_color,
29 ml_self_illum_amnt, ml_diffuse_level, ml_diffuse_rough,
30 ml_specular1, ml_specular_level1, ml_glossiness1, ml_anisotropy1, ml_orientation1,
31 ml_specular2, ml_specular_level2, ml_glossiness2, ml_anisotropy2, ml_orientation2,
32 ml_map_channel, ml_ad_texlock, ml_ad_lock, ml_use_self_illum_color,
33 };
34
35
36
37 /////////////////////////////////////////////////////////////////////
38 //
39 // Basic Panel UI
40 //
41 #define MULTI_LAYER_NMBUTS 16
42 #define N_TR_BUT 15
43
44 // tex channel number to button IDC
45 static int texMButtonsIDC[] = {
46 IDC_MAPON_AM, IDC_MAPON_DI, IDC_MAPON_DIFFLEV, IDC_MAPON_DIFFROUGH,
47 IDC_MAPON_SPECCLR1, IDC_MAPON_SPECLEV1, IDC_MAPON_GL1, IDC_MAPON_AN1, IDC_MAPON_OR1,
48 IDC_MAPON_SPECCLR2, IDC_MAPON_SPECLEV2, IDC_MAPON_GL2, IDC_MAPON_AN2, IDC_MAPON_OR2,
49 IDC_MAPON_SI, IDC_MAPON_TR,
50 -1, -1, -1, -1, -1, -1, -1, -1
51 };
52
53 // This array gives the texture map number for given MButton number
54 static int texmapFromMBut[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
55
56 // Texture Maps
57 #define MULTI_LAYER_NTEXMAPS 17
58
59 // channels ids needed by shader
60 #define _AMBCLR 0
61 #define _DIFFCLR 1
62 #define _DIFFLEV 2
63 #define _DIFFROUGH 3
64 #define _SPECCLR1 4
65 #define _SPECLEV1 5
66 #define _GL1 6
67 #define _AN1 7
68 #define _OR1 8
69 #define _SPECCLR2 9
70 #define _SPECLEV2 10
71 #define _GL2 11
72 #define _AN2 12
73 #define _OR2 13
74 #define _SI 14
75 #define _TR 15
76
77 // channel names
78 static int texNameIDS[STD2_NMAX_TEXMAPS] = {
79 IDS_DS_AMBIENT, IDS_DS_DIFFUSE, IDS_KE_DIFF_LEVEL, IDS_KE_DIFF_ROUGH,
80 IDS_KE_SPEC_CLR1, IDS_KE_SPEC_LEVEL1, IDS_KE_GLOSS1, IDS_KE_ANISO1, IDS_KE_ORIENTATION1,
81 IDS_KE_SPEC_CLR2, IDS_KE_SPEC_LEVEL2, IDS_KE_GLOSS2, IDS_KE_ANISO2, IDS_KE_ORIENTATION2,
82 IDS_KE_SELFILLUM, IDS_DS_TRANS, IDS_DS_FILTER,
83 IDS_KE_NONE, IDS_KE_NONE, IDS_KE_NONE, IDS_KE_NONE,
84 IDS_KE_NONE, IDS_KE_NONE, IDS_KE_NONE,
85 };
86
87 // internal non-local parsable channel map names
88 static TCHAR* texInternalNames[STD2_NMAX_TEXMAPS] = {
89 _T("ambientMap"), _T("diffuseMap"), _T("diffuseLevelMap"), _T("diffuseRoughnessMap"),
90 _T("specularMap"), _T("specularLevelMap"), _T("glossinessMap"), _T("anisotropyMap"), _T("orientationMap"),
91 _T("specularMap2"), _T("specularLevelMap2"), _T("glossinessMap2"), _T("anisotropyMap2"), _T("orientationMap2"),
92 _T("selfIllumMap"), _T("opacityMap"), _T("filterMap"),
93 _T(""), _T(""), _T(""), _T(""),
94 _T(""), _T(""), _T(""),
95 };
96
97
98 // sized for nmax textures
99 // bump, reflection & refraction maps are ignored....done after shading
100 static int chanType[STD2_NMAX_TEXMAPS] = {
101 CLR_CHANNEL, CLR_CHANNEL, MONO_CHANNEL, MONO_CHANNEL,
102 CLR_CHANNEL, SLEV_CHANNEL, MONO_CHANNEL, MONO_CHANNEL, MONO_CHANNEL,
103 CLR_CHANNEL, SLEV_CHANNEL, MONO_CHANNEL, MONO_CHANNEL, MONO_CHANNEL,
104 CLR_CHANNEL, MONO_CHANNEL, CLR_CHANNEL,
105 UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL,UNSUPPORTED_CHANNEL,
106 UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL,
107 };
108
109 // what channel corresponds to the stdMat ID's
110 static int stdIDToChannel[N_ID_CHANNELS] = { 0, 1, 4, 6, 5, 14, 15, 16, -1, -1, -1, -1, -1, -1, -1, -1 };
111
112 //////////////////////////////////////////////////////////////////////////////////////////
113 //
114 // MultiLayer Parameter Block
115 //
116 #define CURRENT_MULTI_LAYER_SHADER_VERSION 2
117 #define MULTI_LAYER_SHADER_NPARAMS 17
118 #define MULTI_LAYER_SHADER_PB_VERSION 1
119 #define MULTI_LAYER_NCOLBOX 5
120
121 static int colID[MULTI_LAYER_NCOLBOX] = { IDC_AMB_CLR, IDC_DIFF_CLR, IDC_SI_CLR, IDC_SPEC_CLR1, IDC_SPEC_CLR2 };
122 #define N_SI_CLR 2
123
124 #define PB_AMB_CLR 0
125 #define PB_DIFF_CLR 1
126 #define PB_DIFF_LEV 2
127 #define PB_DIFF_ROUGH 3
128 #define PB_SPEC_CLR1 4
129 #define PB_SPEC_LEV1 5
130 #define PB_GLOSS1 6
131 #define PB_ANISO1 7
132 #define PB_SPEC_CLR2 8
133 #define PB_SPEC_LEV2 9
134 #define PB_GLOSS2 10
135 #define PB_ANISO2 11
136 #define PB_SELFILLUM_CLR 12
137 #define PB_SELFILLUM_LEV 13
138 #define PB_ORIENTATION1 14
139 #define PB_ORIENTATION2 15
140 #define PB_MAP_CHANNEL 16
141
142 #define ANIMATE TRUE
143 #define NO_ANIMATE FALSE
144
145 //Current Param Block Descriptor
146 static ParamBlockDescID MultiLayerShaderPB[ MULTI_LAYER_SHADER_NPARAMS ] = {
147 { TYPE_RGBA, NULL, ANIMATE, ml_ambient }, // ambient color
148 { TYPE_RGBA, NULL, ANIMATE, ml_diffuse }, // diffuse color
149 { TYPE_FLOAT, NULL, ANIMATE, ml_diffuse_level }, // diffuse level
150 { TYPE_FLOAT, NULL, ANIMATE, ml_diffuse_rough }, // diffuse roughness
151 { TYPE_RGBA, NULL, ANIMATE, ml_specular1 }, // specular layer 1 color
152 { TYPE_FLOAT, NULL, ANIMATE, ml_specular_level1 }, // layer 1 level
153 { TYPE_FLOAT, NULL, ANIMATE, ml_glossiness1 }, // layer 1 gloss
154 { TYPE_FLOAT, NULL, ANIMATE, ml_anisotropy1 }, // layer 1 anisotropy
155 { TYPE_RGBA, NULL, ANIMATE, ml_specular2 }, // Specular layer 2 color
156 { TYPE_FLOAT, NULL, ANIMATE, ml_specular_level2 }, // layer 2 level
157 { TYPE_FLOAT, NULL, ANIMATE, ml_glossiness2 }, // layer 2 gloss
158 { TYPE_FLOAT, NULL, ANIMATE, ml_anisotropy2 }, // layer 2 anisotropy
159 { TYPE_RGBA, NULL, ANIMATE, ml_self_illum_color }, // selfIllumClr
160 { TYPE_FLOAT, NULL, ANIMATE, ml_self_illum_amnt}, // selfIllumLevel
161 { TYPE_FLOAT, NULL, ANIMATE, ml_orientation1 }, // orientation1
162 { TYPE_FLOAT, NULL, ANIMATE, ml_orientation2 }, // orientation2
163 { TYPE_INT, NULL, NO_ANIMATE, ml_map_channel } // map channel
164 };
165
166
167 #define MULTI_LAYER_NUMVER 1
168
169 static ParamVersionDesc oldVersions[MULTI_LAYER_NUMVER] = {
170 ParamVersionDesc(MultiLayerShaderPB, MULTI_LAYER_SHADER_NPARAMS, 0),
171 };
172
173 //----------------------------------------------------------------------------------------
174 //---- MultiLayer: A 2 layer physically based anisotropic shader -------------------------------
175 //----------------------------------------------------------------------------------------
176
177 class MultiLayerShaderDlg;
178
179 class MultiLayerShader : public ExposureMaterialControlImp<MultiLayerShader, CombineComponentsCompShader> {
180 friend class MultiLayerShaderCB;
181 friend class MultiLayerShaderDlg;
182 friend class ExposureMaterialControlImp<MultiLayerShader, CombineComponentsCompShader>;
183 protected:
184 IParamBlock2 *pblock; // ref 0
185 Interval ivalid;
186
187 MultiLayerShaderDlg* paramDlg;
188
189 Color ambColor;
190 Color diffColor;
191 float diffLevel;
192 float diffRough;
193
194 Color specColor1;
195 float specLevel1;
196 float gloss1;
197 float aniso1;
198 float orientation1;
199
200 Color specColor2;
201 float specLevel2;
202 float gloss2;
203 float aniso2;
204 float orientation2;
205
206 float selfIllumLevel;
207 Color selfIllum;
208 BOOL selfIllumClrOn;
209
210
211 BOOL lockAD;
212 BOOL lockADTex;
213
214 BOOL rolloutOpen;
215
216
217 static CombineComponentsFPDesc msExpMtlControlDesc;
218
219 public:
220 MultiLayerShader();
DeleteThis()221 void DeleteThis(){ delete this; }
SupportStdParams()222 ULONG SupportStdParams(){ return (STD_MULTILAYER | STD_EXTRA); }
223
224 // copy std params, for switching shaders
225 void CopyStdParams( Shader* pFrom );
226
227 // texture maps
nTexChannelsSupported()228 long nTexChannelsSupported(){ return MULTI_LAYER_NTEXMAPS; }
GetTexChannelName(long nTex)229 TSTR GetTexChannelName( long nTex ){ return GetString( texNameIDS[ nTex ] ); }
GetTexChannelInternalName(long nTex)230 TSTR GetTexChannelInternalName( long nTex ){ return texInternalNames[ nTex ]; }
ChannelType(long nChan)231 long ChannelType( long nChan ) { return chanType[nChan]; }
StdIDToChannel(long stdID)232 long StdIDToChannel( long stdID ){ return stdIDToChannel[stdID]; }
233
KeyAtTime(int id,TimeValue t)234 BOOL KeyAtTime(int id,TimeValue t) { return pblock->KeyFrameAtTime(id,t); }
235
236 ShaderParamDlg* CreateParamDialog(HWND hOldRollup, HWND hwMtlEdit, IMtlParams *imp, StdMat2* theMtl, int rollupOpen, int );
GetParamDlg(int)237 ShaderParamDlg* GetParamDlg(int){ return (ShaderParamDlg*)paramDlg; }
SetParamDlg(ShaderParamDlg * newDlg,int)238 void SetParamDlg( ShaderParamDlg* newDlg, int ){ paramDlg = (MultiLayerShaderDlg*)newDlg; }
239
ClassID()240 Class_ID ClassID() { return MultiLayerShaderClassID; }
SuperClassID()241 SClass_ID SuperClassID() { return SHADER_CLASS_ID; }
GetName()242 TSTR GetName() { return GetString( IDS_KE_MULTI_LAYER ); }
GetClassName(TSTR & s)243 void GetClassName(TSTR& s) { s = GetName(); }
244
NumSubs()245 int NumSubs() { return 1; }
SubAnim(int i)246 Animatable* SubAnim(int i){ return (i==0)? pblock : NULL; }
SubAnimName(int i)247 TSTR SubAnimName(int i){ return TSTR(GetString( IDS_KE_MULTI_LAYER_PARMS )); };
SubNumToRefNum(int subNum)248 int SubNumToRefNum(int subNum) { return subNum; }
249
250 // add direct ParamBlock2 access
NumParamBlocks()251 int NumParamBlocks() { return 1; }
GetParamBlock(int i)252 IParamBlock2* GetParamBlock(int i) { return pblock; }
GetParamBlockByID(BlockID id)253 IParamBlock2* GetParamBlockByID(BlockID id) { return (pblock->ID() == id) ? pblock : NULL; }
254
NumRefs()255 int NumRefs() { return 1; }
GetReference(int i)256 RefTargetHandle GetReference(int i){ return (i==0)? pblock : NULL; }
SetReference(int i,RefTargetHandle rtarg)257 void SetReference(int i, RefTargetHandle rtarg)
258 { if (i==0) pblock = (IParamBlock2*)rtarg; else assert(0); }
NotifyChanged()259 void NotifyChanged(){ NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); }
260
261 void Update(TimeValue t, Interval& valid);
262 void Reset();
263 RefTargetHandle Clone( RemapDir &remap=DefaultRemapDir() );
264 RefResult NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget,
265 PartID& partID, RefMessage message );
266 // IO
267 IOResult Save(ISave *isave);
268 IOResult Load(ILoad *iload);
269
270 // cache for mapping of params, mtl fills in ip
271 void GetIllumParams( ShadeContext &sc, IllumParams& ip );
272
273 // MultiLayer Shader specific section
274 void PreShade(ShadeContext& sc, IReshadeFragment* pFrag);
275 void PostShade(ShadeContext& sc, IReshadeFragment* pFrag, int& nextTexIndex, IllumParams* ip);
276 void Illum(ShadeContext &sc, IllumParams &ip);
277 void InternalIllum(ShadeContext &sc, IllumParams &ip, Point3* pTangent );
278 float EvalHiliteCurve2(float x, float y, int layer ); // layer is 1 or 2
279 void AffectReflection(ShadeContext &sc, IllumParams &ip, Color &rcol);
280
SetGlossiness(float v,TimeValue t)281 void SetGlossiness(float v, TimeValue t)
282 { gloss1= v; pblock->SetValue( ml_glossiness1, t, v); }
SetGlossiness1(float v,TimeValue t)283 void SetGlossiness1(float v, TimeValue t)
284 { gloss1= v; pblock->SetValue( ml_glossiness1, t, v); }
SetAnisotropy1(float v,TimeValue t)285 void SetAnisotropy1(float v, TimeValue t)
286 { aniso1 = v; pblock->SetValue( ml_anisotropy1, t, v); }
SetSpecLevel1(float v,TimeValue t)287 void SetSpecLevel1(float v, TimeValue t)
288 { specLevel1 = v; pblock->SetValue( ml_specular_level1, t, v); }
SetOrientation1(float v,TimeValue t)289 void SetOrientation1(float v, TimeValue t)
290 { orientation1 = v; pblock->SetValue( ml_orientation1, t, v); }
SetOrientation2(float v,TimeValue t)291 void SetOrientation2(float v, TimeValue t)
292 { orientation2 = v; pblock->SetValue( ml_orientation2, t, v); }
GetGlossiness(int mtlNum,BOOL backFace)293 float GetGlossiness(int mtlNum, BOOL backFace){ return gloss1; }
GetGlossiness1(int mtlNum,BOOL backFace)294 float GetGlossiness1(int mtlNum, BOOL backFace){ return gloss1; }
GetAnisotropy1(int mtlNum,BOOL backFace)295 float GetAnisotropy1(int mtlNum, BOOL backFace){ return aniso1; }
GetSpecLevel1(int mtlNum,BOOL backFace)296 float GetSpecLevel1(int mtlNum, BOOL backFace){ return specLevel1; }
GetOrientation1(int mtlNum,BOOL backFace)297 float GetOrientation1(int mtlNum, BOOL backFace){ return orientation1; }
GetOrientation2(int mtlNum,BOOL backFace)298 float GetOrientation2(int mtlNum, BOOL backFace){ return orientation2; }
GetGlossiness(TimeValue t)299 float GetGlossiness( TimeValue t){return pblock->GetFloat(ml_glossiness1,t); }
GetGlossiness1(TimeValue t)300 float GetGlossiness1( TimeValue t){return pblock->GetFloat(ml_glossiness1,t); }
GetAnisotropy1(TimeValue t)301 float GetAnisotropy1( TimeValue t){return pblock->GetFloat(ml_anisotropy1,t); }
GetSpecLevel1(TimeValue t)302 float GetSpecLevel1( TimeValue t){return pblock->GetFloat(ml_specular_level1,t); }
GetOrientation1(TimeValue t)303 float GetOrientation1( TimeValue t){return pblock->GetFloat(ml_orientation1,t); }
GetOrientation2(TimeValue t)304 float GetOrientation2( TimeValue t){return pblock->GetFloat(ml_orientation2,t); }
305
SetGlossiness2(float v,TimeValue t)306 void SetGlossiness2(float v, TimeValue t)
307 { gloss2= v; pblock->SetValue( ml_glossiness2, t, v); }
SetAnisotropy2(float v,TimeValue t)308 void SetAnisotropy2(float v, TimeValue t)
309 { aniso2 = v; pblock->SetValue( ml_anisotropy2, t, v); }
SetSpecLevel2(float v,TimeValue t)310 void SetSpecLevel2(float v, TimeValue t)
311 { specLevel2 = v; pblock->SetValue( ml_specular_level2, t, v); }
GetGlossiness2(int mtlNum,BOOL backFace)312 float GetGlossiness2(int mtlNum, BOOL backFace){ return gloss2; };
GetAnisotropy2(int mtlNum,BOOL backFace)313 float GetAnisotropy2(int mtlNum, BOOL backFace){ return aniso2; };
GetSpecLevel2(int mtlNum,BOOL backFace)314 float GetSpecLevel2(int mtlNum, BOOL backFace){ return specLevel2; };
GetGlossiness2(TimeValue t)315 float GetGlossiness2( TimeValue t){return pblock->GetFloat(ml_glossiness2,t); }
GetAnisotropy2(TimeValue t)316 float GetAnisotropy2( TimeValue t){return pblock->GetFloat(ml_anisotropy2,t); }
GetSpecLevel2(TimeValue t)317 float GetSpecLevel2( TimeValue t){return pblock->GetFloat(ml_specular_level2,t); }
318
SetDiffuseLevel(float v,TimeValue t)319 void SetDiffuseLevel(float v, TimeValue t)
320 { diffLevel = v; pblock->SetValue( ml_diffuse_level, t, v); }
GetDiffuseLevel(int mtlNum,BOOL backFace)321 float GetDiffuseLevel(int mtlNum, BOOL backFace){ return diffLevel; }
GetDiffuseLevel(TimeValue t)322 float GetDiffuseLevel( TimeValue t ){ return pblock->GetFloat(ml_diffuse_level,t); }
SetDiffuseRough(float v,TimeValue t)323 void SetDiffuseRough(float v, TimeValue t)
324 { diffRough = v; pblock->SetValue( ml_diffuse_rough, t, v); }
GetDiffuseRough(int mtlNum,BOOL backFace)325 float GetDiffuseRough(int mtlNum, BOOL backFace){ return diffRough; }
GetDiffuseRough(TimeValue t)326 float GetDiffuseRough( TimeValue t ){ return pblock->GetFloat(ml_diffuse_rough,t); }
327
SetSpecColor1(Color c,TimeValue t)328 void SetSpecColor1(Color c, TimeValue t)
329 { specColor1 = c; pblock->SetValue( ml_specular1, t, c); }
SetSpecColor2(Color c,TimeValue t)330 void SetSpecColor2(Color c, TimeValue t)
331 { specColor2 = c; pblock->SetValue( ml_specular2, t, c); }
332
GetSpecColor1(int mtlNum,BOOL backFace)333 Color GetSpecColor1(int mtlNum, BOOL backFace){ return specColor1;}
GetSpecColor1(TimeValue t)334 Color GetSpecColor1(TimeValue t){ return pblock->GetColor(ml_specular1,t); }
GetSpecColor2(int mtlNum,BOOL backFace)335 Color GetSpecColor2(int mtlNum, BOOL backFace){ return specColor2; }
GetSpecColor2(TimeValue t)336 Color GetSpecColor2(TimeValue t){ return pblock->GetColor(ml_specular2,t); }
337
338 // Std Params, these define the interactive settings for OGL, etc....
SetAmbientClr(Color c,TimeValue t)339 void SetAmbientClr(Color c, TimeValue t)
340 { ambColor = c; pblock->SetValue( ml_ambient, t, c); }
SetDiffuseClr(Color c,TimeValue t)341 void SetDiffuseClr(Color c, TimeValue t)
342 { diffColor = c; pblock->SetValue( ml_diffuse, t, c); }
SetSpecularClr(Color c,TimeValue t)343 void SetSpecularClr(Color c, TimeValue t)
344 { SetSpecColor1( c, t ); }
SetSelfIllumClr(Color c,TimeValue t)345 void SetSelfIllumClr(Color c, TimeValue t)
346 { selfIllum = c; pblock->SetValue( ml_self_illum_color, t, c); }
SetSpecularLevel(float v,TimeValue t)347 void SetSpecularLevel(float v, TimeValue t)
348 {SetSpecLevel1( v, t ); }
SetSelfIllum(float v,TimeValue t)349 void SetSelfIllum(float v, TimeValue t)
350 { selfIllumLevel = v; pblock->SetValue( ml_self_illum_amnt, t, v); }
351
GetAmbientClr(int mtlNum,BOOL backFace)352 Color GetAmbientClr(int mtlNum, BOOL backFace ){ return ambColor;}
GetDiffuseClr(int mtlNum,BOOL backFace)353 Color GetDiffuseClr(int mtlNum, BOOL backFace ){ return diffColor;}
GetSpecularClr(int mtlNum,BOOL backFace)354 Color GetSpecularClr(int mtlNum, BOOL backFace ){ return specColor1; }
GetSelfIllumClr(int mtlNum,BOOL backFace)355 Color GetSelfIllumClr(int mtlNum, BOOL backFace ){ return selfIllum; }
GetSelfIllum(int mtlNum,BOOL backFace)356 float GetSelfIllum(int mtlNum, BOOL backFace ){ return selfIllumLevel; }
GetSpecularLevel(int mtlNum,BOOL backFace)357 float GetSpecularLevel(int mtlNum, BOOL backFace ){ return specLevel1; }
358
GetAmbientClr(TimeValue t)359 Color GetAmbientClr(TimeValue t){ return pblock->GetColor(ml_ambient,t); }
GetDiffuseClr(TimeValue t)360 Color GetDiffuseClr(TimeValue t){ return pblock->GetColor(ml_diffuse,t); }
GetSpecularClr(TimeValue t)361 Color GetSpecularClr(TimeValue t){ return GetSpecColor1( t ); }
GetSelfIllumClr(TimeValue t)362 Color GetSelfIllumClr(TimeValue t){ return pblock->GetColor(ml_self_illum_color,t);}
GetSelfIllum(TimeValue t)363 float GetSelfIllum(TimeValue t){ return pblock->GetFloat(ml_self_illum_amnt,t);}
GetSpecularLevel(TimeValue t)364 float GetSpecularLevel( TimeValue t){return GetSpecLevel1( t ); }
365
SetSelfIllumClrOn(BOOL on)366 void SetSelfIllumClrOn( BOOL on ){ selfIllumClrOn = on; pblock->SetValue( ml_use_self_illum_color, 0, on); }
IsSelfIllumClrOn()367 BOOL IsSelfIllumClrOn(){ return selfIllumClrOn; }
IsSelfIllumClrOn(int mtlNum,BOOL backFace)368 BOOL IsSelfIllumClrOn(int mtlNum, BOOL backFace){ return selfIllumClrOn; }
369
SetLockAD(BOOL lock)370 void SetLockAD(BOOL lock){ lockAD = lock; pblock->SetValue( ml_ad_lock, 0, lock); }
GetLockAD()371 BOOL GetLockAD(){ return lockAD; }
SetLockADTex(BOOL lock)372 void SetLockADTex(BOOL lock){ lockADTex = lock; pblock->SetValue( ml_ad_texlock, 0, lock); }
GetLockADTex()373 BOOL GetLockADTex(){ return lockADTex; }
374
375 // not supported
SetSoftenLevel(float v,TimeValue t)376 void SetSoftenLevel(float v, TimeValue t) {}
GetSoftenLevel(int mtlNum=0,BOOL backFace=FALSE)377 float GetSoftenLevel(int mtlNum=0, BOOL backFace=FALSE){ return DEFAULT_SOFTEN; }
GetSoftenLevel(TimeValue t)378 float GetSoftenLevel(TimeValue t){ return DEFAULT_SOFTEN; }
SetLockDS(BOOL lock)379 void SetLockDS(BOOL lock){}
GetLockDS()380 BOOL GetLockDS(){ return FALSE; }
381
SetPanelOpen(BOOL open)382 void SetPanelOpen(BOOL open){rolloutOpen = open;}
383
384 };
385
386 ///////////// Class Descriptor ////////////////////////
387 class MultiLayerShaderClassDesc : public ClassDesc2 {
388 public:
IsPublic()389 int IsPublic() { return 1; }
Create(BOOL loading)390 void * Create(BOOL loading) { return new MultiLayerShader(); }
ClassName()391 const TCHAR * ClassName() { return GetString(IDS_KE_MULTI_LAYER); }
SuperClassID()392 SClass_ID SuperClassID() { return SHADER_CLASS_ID; }
ClassID()393 Class_ID ClassID() { return MultiLayerShaderClassID; }
Category()394 const TCHAR* Category() { return _T(""); }
InternalName()395 const TCHAR* InternalName() { return _T("MultiLayer"); } // returns fixed parsable name (scripter-visible name)
HInstance()396 HINSTANCE HInstance() { return hInstance; } // returns owning module handle
397 };
398
399 MultiLayerShaderClassDesc multiLayerCD;
GetMultiLayerShaderCD()400 ClassDesc * GetMultiLayerShaderCD(){ return &multiLayerCD; }
401
402 // shader parameters
403 static ParamBlockDesc2 multiLayer_param_blk ( multiLayer_params, _T("shaderParameters"), 0, &multiLayerCD, P_AUTO_CONSTRUCT, 0,
404 // params
405 ml_ambient, _T("ambient"), TYPE_RGBA, P_ANIMATABLE, IDS_DS_AMBIENT,
406 p_default, Color(0, 0, 0),
407 end,
408 ml_diffuse, _T("diffuse"), TYPE_RGBA, P_ANIMATABLE, IDS_DS_DIFFUSE,
409 p_default, Color(0.5f, 0.5f, 0.5f),
410 end,
411 ml_self_illum_color, _T("selfIllumColor"), TYPE_RGBA, P_ANIMATABLE, IDS_KE_SELFILLUM_CLR,
412 p_default, Color(0, 0, 0),
413 end,
414 ml_self_illum_amnt, _T("selfIllumAmount"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_KE_SELFILLUM,
415 p_default, 0.0,
416 p_range, 0.0, 100.0,
417 end,
418 ml_diffuse_level, _T("diffuseLevel"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_KE_DIFF_LEVEL,
419 p_default, 100.0,
420 p_range, 0.0, 400.0,
421 end,
422 ml_diffuse_rough, _T("diffuseRoughness"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_KE_DIFF_ROUGH,
423 p_default, 0.0,
424 p_range, 0.0, 100.0,
425 end,
426 ml_specular1, _T("specular"), TYPE_RGBA, P_ANIMATABLE, IDS_KE_CLR1,
427 p_default, Color(1.0f, 1.0f, 1.0f),
428 end,
429 ml_specular_level1, _T("specularLevel"), TYPE_PCNT_FRAC, P_ANIMATABLE,IDS_KE_LEVEL1,
430 p_default, 10.0,
431 p_range, 0.0, 999.0,
432 end,
433 ml_glossiness1, _T("glossiness"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_KE_GLOSS1,
434 p_default, 25.0,
435 p_range, 0.0, 100.0,
436 end,
437 ml_anisotropy1, _T("anisotropy"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_KE_ANISO1,
438 p_default, 0.0,
439 p_range, 0.0, 100.0,
440 end,
441 ml_orientation1, _T("orientation"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_KE_ORIENTATION1,
442 p_default, 0.0,
443 p_range, MIN_ORIENT*100.0, MAX_ORIENT*100.0,
444 end,
445 ml_specular2, _T("specular2"), TYPE_RGBA, P_ANIMATABLE, IDS_KE_CLR2,
446 p_default, Color(1.0f, 1.0f, 1.0f),
447 end,
448 ml_specular_level2, _T("specularLevel2"), TYPE_PCNT_FRAC, P_ANIMATABLE,IDS_KE_LEVEL2,
449 p_default, 0.0,
450 p_range, 0.0, 999.0,
451 end,
452 ml_glossiness2, _T("glossiness2"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_KE_GLOSS2,
453 p_default, 25.0,
454 p_range, 0.0, 100.0,
455 end,
456 ml_anisotropy2, _T("anisotropy2"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_KE_ANISO2,
457 p_default, 0.0,
458 p_range, 0.0, 100.0,
459 end,
460 ml_orientation2, _T("orientation2"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_KE_ORIENTATION2,
461 p_default, 0.0,
462 p_range, MIN_ORIENT*100.0, MAX_ORIENT*100.0,
463 end,
464 ml_map_channel, _T("unused"), TYPE_INT, 0, IDS_KE_MAPCHANNEL,
465 p_default, 0,
466 p_range, 0, 16,
467 end,
468 ml_ad_texlock, _T("adTextureLock"), TYPE_BOOL, 0, IDS_JW_ADTEXLOCK,
469 p_default, TRUE,
470 end,
471 ml_ad_lock, _T("adLock"), TYPE_BOOL, 0, IDS_JW_ADLOCK,
472 p_default, TRUE,
473 end,
474 ml_use_self_illum_color, _T("useSelfIllumColor"), TYPE_BOOL, 0, IDS_JW_SELFILLUMCOLORON,
475 p_default, FALSE,
476 end,
477 end
478 );
479
480
481
482 CombineComponentsFPDesc MultiLayerShader::msExpMtlControlDesc(multiLayerCD);
483
MultiLayerShader()484 MultiLayerShader::MultiLayerShader()
485 {
486 pblock = NULL;
487 multiLayerCD.MakeAutoParamBlocks(this); // make and intialize paramblock2
488 paramDlg = NULL;
489
490 selfIllumClrOn = 0;
491 lockAD = lockADTex = TRUE;
492 ambColor = diffColor = specColor1 = specColor2 = selfIllum = Color(0.0f,0.0f,0.0f);
493 gloss1 = orientation1 = aniso1 = specLevel1
494 = gloss2 = orientation2 = aniso2 = specLevel2
495 = diffLevel = diffRough = selfIllumLevel = 0.0f;
496
497 ivalid.SetEmpty();
498
499 rolloutOpen = TRUE;
500
501 }
502
503
CopyStdParams(Shader * pFrom)504 void MultiLayerShader::CopyStdParams( Shader* pFrom )
505 {
506 macroRecorder->Disable();
507 // don't want to see this parameter copying in macrorecorder
508 long fromParms = pFrom->SupportStdParams();
509
510 if ( fromParms & STD_PARAM_SELFILLUM_CLR_ON )
511 SetSelfIllumClrOn( pFrom->IsSelfIllumClrOn() );
512
513 if ( fromParms & STD_PARAM_AMBIENT_CLR )
514 SetAmbientClr( pFrom->GetAmbientClr(0,0), 0 );
515
516 if ( fromParms & STD_PARAM_DIFFUSE_CLR )
517 SetDiffuseClr( pFrom->GetDiffuseClr(0,0), 0 );
518
519 if ( fromParms & STD_PARAM_SPECULAR_CLR )
520 SetSpecularClr( pFrom->GetSpecularClr(0,0), 0 );
521
522 if ( fromParms & STD_PARAM_SELFILLUM_CLR )
523 SetSelfIllumClr( pFrom->GetSelfIllumClr(0,0), 0 );
524
525 if ( fromParms & STD_PARAM_SPECULAR_LEV )
526 SetSpecularLevel( pFrom->GetSpecularLevel(0,0), 0 );
527
528 if ( fromParms & STD_PARAM_GLOSSINESS )
529 SetGlossiness( pFrom->GetGlossiness(0,0), 0 );
530
531 if ( fromParms & STD_PARAM_SELFILLUM )
532 SetSelfIllum( pFrom->GetSelfIllum(0,0), 0 );
533
534 if ( fromParms & STD_PARAM_LOCKAD )
535 SetLockAD( pFrom->GetLockAD() );
536
537 if ( fromParms & STD_PARAM_LOCKADTEX )
538 SetLockADTex( pFrom->GetLockADTex() );
539
540 macroRecorder->Enable();
541 ivalid.SetEmpty();
542 }
543
544
Clone(RemapDir & remap)545 RefTargetHandle MultiLayerShader::Clone( RemapDir &remap )
546 {
547 MultiLayerShader* mnew = new MultiLayerShader();
548 mnew->ExposureMaterialControl::operator=(*this);
549 mnew->ReplaceReference(0, remap.CloneRef(pblock));
550 mnew->ivalid.SetEmpty();
551
552 mnew->ambColor = ambColor;
553 mnew->diffColor = diffColor;
554
555 mnew->diffLevel = diffLevel;
556 mnew->diffRough = diffRough;
557
558 mnew->selfIllum = selfIllum;
559 mnew->selfIllumLevel = selfIllumLevel;
560 mnew->selfIllumClrOn = selfIllumClrOn;
561
562 mnew->specColor1 = specColor1;
563 mnew->specLevel1 = specLevel1;
564 mnew->gloss1 = gloss1;
565 mnew->aniso1 = aniso1;
566 mnew->orientation1 = orientation1;
567
568 mnew->specColor2 = specColor2;
569 mnew->specLevel2 = specLevel2;
570 mnew->gloss2 = gloss2;
571 mnew->aniso2 = aniso2;
572 mnew->orientation2 = orientation2;
573
574 mnew->lockAD = lockAD;
575 mnew->lockADTex = lockADTex;
576
577 BaseClone(this, mnew, remap);
578 return (RefTargetHandle)mnew;
579 }
580
581
GetIllumParams(ShadeContext & sc,IllumParams & ip)582 void MultiLayerShader::GetIllumParams( ShadeContext &sc, IllumParams& ip )
583 {
584 ip.stdParams = SupportStdParams();
585 ip.channels[_AMBCLR] = lockAD? diffColor : ambColor;
586 ip.channels[_DIFFCLR] = diffColor;
587 ip.channels[_DIFFLEV].r = diffLevel;
588 ip.channels[_DIFFROUGH].r = diffRough;
589
590 ip.channels[_SPECCLR1] = specColor1;
591 ip.channels[_SPECCLR2] = specColor2;
592
593 ip.channels[_SPECLEV1].r = specLevel1;
594 ip.channels[_GL1].r = gloss1;
595 ip.channels[_AN1].r = aniso1;
596 ip.channels[_OR1].r = orientation1 * (1.0f/1.8f); // this range for mono texturing, 0..1
597
598 ip.channels[_SPECLEV2].r = specLevel2;
599 ip.channels[_GL2].r = gloss2;
600 ip.channels[_AN2].r = aniso2;
601 ip.channels[_OR2].r = orientation2 * (1.0f/1.8f);
602
603 if (selfIllumClrOn )
604 ip.channels[_SI] = selfIllum;
605 else
606 ip.channels[_SI].r=ip.channels[_SI].g=ip.channels[_SI].b = selfIllumLevel;
607 }
608
609 static BOOL inUpdate = FALSE;
610
611
Update(TimeValue t,Interval & valid)612 void MultiLayerShader::Update(TimeValue t, Interval &valid) {
613 Point3 p, p2;
614 if( inUpdate )
615 return;
616 inUpdate = TRUE;
617 if (!ivalid.InInterval(t)) {
618 ivalid.SetInfinite();
619
620 // pblock->GetValue( ml_ambient, t, p, ivalid );
621 // ambColor = Bound(Color(p.x,p.y,p.z));
622 pblock->GetValue( ml_diffuse, t, p, ivalid );
623 diffColor = Bound(Color(p.x,p.y,p.z));
624 pblock->GetValue( ml_ambient, t, p2, ivalid );
625 if( lockAD && (p!=p2)){
626 pblock->SetValue( ml_ambient, t, diffColor);
627 ambColor = diffColor;
628 } else {
629 pblock->GetValue( ml_ambient, t, p, ivalid );
630 ambColor = Bound(Color(p.x,p.y,p.z));
631 }
632 pblock->GetValue( ml_diffuse_level, t, diffLevel, ivalid );
633 diffLevel = Bound(diffLevel, 0.0f, 4.0f );
634 pblock->GetValue( ml_diffuse_rough, t, diffRough, ivalid );
635 diffRough = Bound(diffRough);
636
637 pblock->GetValue( ml_specular1, t, p, ivalid );
638 specColor1 = Bound(Color(p.x,p.y,p.z));
639 pblock->GetValue( ml_specular_level1, t, specLevel1, ivalid );
640 specLevel1 = Bound( specLevel1, 0.0f, 9.99f );
641 pblock->GetValue( ml_glossiness1, t, gloss1, ivalid );
642 gloss1 = Bound( gloss1 );
643 pblock->GetValue( ml_anisotropy1, t, aniso1, ivalid );
644 aniso1 = Bound( aniso1 );
645 pblock->GetValue( ml_orientation1, t, orientation1, ivalid );
646 orientation1 = Bound( orientation1, (float)MIN_ORIENT, (float)MAX_ORIENT );
647
648 pblock->GetValue( ml_specular2, t, p, ivalid );
649 specColor2 = Bound(Color(p.x,p.y,p.z));
650 pblock->GetValue( ml_specular_level2, t, specLevel2, ivalid );
651 specLevel2 = Bound( specLevel2, 0.0f, 9.99f );
652 pblock->GetValue( ml_glossiness2, t, gloss2, ivalid );
653 gloss2 = Bound( gloss2 );
654 pblock->GetValue( ml_anisotropy2, t, aniso2, ivalid );
655 aniso2 = Bound( aniso2 );
656 pblock->GetValue( ml_orientation2, t, orientation2, ivalid );
657 orientation2 = Bound( orientation2, (float)MIN_ORIENT, (float)MAX_ORIENT );
658
659 pblock->GetValue( ml_self_illum_amnt, t, selfIllumLevel, ivalid );
660 selfIllumLevel = Bound(selfIllumLevel);
661 pblock->GetValue( ml_self_illum_color, t, p, ivalid );
662 selfIllum = Bound(Color(p.x,p.y,p.z));
663
664 // also get the non-animatables in case changed from scripter or other pblock accessors
665 pblock->GetValue(ml_ad_lock, t, lockAD, ivalid);
666 pblock->GetValue(ml_ad_texlock, t, lockADTex, ivalid);
667 pblock->GetValue(ml_use_self_illum_color, t, selfIllumClrOn, ivalid);
668
669 }
670 valid &= ivalid;
671 inUpdate = FALSE;
672 }
673
Reset()674 void MultiLayerShader::Reset()
675 {
676 // multiLayerCD.MakeAutoParamBlocks(this); // make and intialize paramblock2
677 ivalid.SetEmpty();
678
679 SetAmbientClr(Color(0.2f,0.2f,0.2f),0);
680 SetDiffuseClr(Color(0.5f,0.5f,0.5f),0);
681 SetDiffuseLevel( 1.0f,0 );
682 SetDiffuseRough( 0.0f,0 );
683
684 SetSpecColor1(Color(0.9f,0.9f,0.9f),0);
685 SetSpecLevel1(0.05f,0);
686 SetGlossiness1(.50f,0);
687 SetAnisotropy1(0.0f,0);
688 SetOrientation1(0.0f,0);
689
690 SetSpecColor2(Color(0.9f,0.9f,0.9f),0);
691 SetSpecLevel2(0.0f,0);
692 SetGlossiness2(.25f,0);
693 SetAnisotropy2(0.0f,0);
694 SetOrientation2(0.0f,0);
695
696 SetSelfIllumClr(Color(0.0f,0.0f,0.0f),0);
697 SetSelfIllum( 0.0f,0 );
698 SetSelfIllumClrOn( FALSE );
699
700 SetLockADTex( TRUE );
701 SetLockAD( TRUE ); // > 6/13/02 - 4:48pm --MQM-- was FALSE
702 }
703
704
705
706 //////////////////////////////////////////////////////////////////////////////////////////
707 //
708 // IO Routines
709 //
710 #define SHADER_HDR_CHUNK 0x4000
711 #define SHADER_VERS_CHUNK 0x5300
712 #define SHADER_SELFILLUMCLR_ON_CHUNK 0x5006
713 #define SHADER_LOCKAD_ON_CHUNK 0x5007
714 #define SHADER_LOCKADTEX_ON_CHUNK 0x5008
715 #define SHADER_EXPOSURE_MATERIAL_CONTROL_CHUNK 0x5020
716
717 // IO
Save(ISave * isave)718 IOResult MultiLayerShader::Save(ISave *isave)
719 {
720 ULONG nb;
721
722 isave->BeginChunk(SHADER_VERS_CHUNK);
723 int version = CURRENT_MULTI_LAYER_SHADER_VERSION;
724 isave->Write(&version,sizeof(version),&nb);
725 isave->EndChunk();
726
727 isave->BeginChunk(SHADER_EXPOSURE_MATERIAL_CONTROL_CHUNK);
728 ExposureMaterialControl::Save(isave);
729 isave->EndChunk();
730 return IO_OK;
731 }
732
733 class MultiLayerShaderCB: public PostLoadCallback {
734 public:
735 MultiLayerShader *s;
736 int loadVersion;
MultiLayerShaderCB(MultiLayerShader * newS,int loadVers)737 MultiLayerShaderCB(MultiLayerShader *newS, int loadVers) { s = newS; loadVersion = loadVers; }
proc(ILoad * iload)738 void proc(ILoad *iload) {
739 // convert old v1 ParamBlock to ParamBlock2
740 s->ReplaceReference(0,
741 UpdateParameterBlock2(MultiLayerShaderPB, MULTI_LAYER_SHADER_NPARAMS, (IParamBlock*)s->pblock, &multiLayer_param_blk));
742
743 // then set values that were previously stored outside the PB
744 s->pblock->SetValue(ml_use_self_illum_color, 0, s->selfIllumClrOn);
745 s->pblock->SetValue(ml_ad_lock, 0, s->lockAD);
746 s->pblock->SetValue(ml_ad_texlock, 0, s->lockADTex);
747 }
748 };
749
750
Load(ILoad * iload)751 IOResult MultiLayerShader::Load(ILoad *iload)
752 {
753 ULONG nb;
754 int id;
755 int version = 0;
756
757 lockAD = lockADTex = selfIllumClrOn = 0;
758
759 IOResult res;
760 while (IO_OK==(res=iload->OpenChunk())) {
761 switch(id = iload->CurChunkID()) {
762 case SHADER_VERS_CHUNK:
763 res = iload->Read(&version,sizeof(version), &nb);
764 break;
765 case SHADER_SELFILLUMCLR_ON_CHUNK:
766 selfIllumClrOn = TRUE;
767 break;
768 case SHADER_LOCKAD_ON_CHUNK:
769 lockAD = TRUE;
770 break;
771 case SHADER_LOCKADTEX_ON_CHUNK:
772 lockADTex = TRUE;
773 break;
774 case SHADER_EXPOSURE_MATERIAL_CONTROL_CHUNK:
775 res = ExposureMaterialControl::Load(iload);
776 break;
777 }
778 iload->CloseChunk();
779 if (res!=IO_OK)
780 return res;
781 }
782 if (version < CURRENT_MULTI_LAYER_SHADER_VERSION ) {
783 iload->RegisterPostLoadCallback(new MultiLayerShaderCB(this, version));
784 iload->SetObsolete();
785 }
786
787 return IO_OK;
788
789 }
790
791
792 ///////////////////////////////////////////////////////////////////////////////////////////
793 // The Shader
794 //
795 // defualt gloss squared, for renormalized controls
796 #define DEFAULT_GLOSS2 0.03f
797
EvalHiliteCurve2(float x,float y,int layer)798 float MultiLayerShader::EvalHiliteCurve2( float x, float y, int layer )
799 {
800 float g = (layer == 1)? gloss1 : gloss2;
801 float a = (layer == 1)? aniso1 : aniso2;
802 float specLevel = (layer == 1)? specLevel1 : specLevel2;
803
804 return GaussHiliteCurve2( x, y, specLevel, g, a);
805
806 }
807
808
AffectReflection(ShadeContext & sc,IllumParams & ip,Color & rcol)809 void MultiLayerShader::AffectReflection(ShadeContext &sc, IllumParams &ip, Color &rcol)
810 {
811 //NB kl,aka NL & g cancel out
812 // rcol *= ip.channels[_SPECLEV1].r * ip.channels[_SPECCLR1] * DEFAULT_K_REFL;
813 rcol *= ip.channels[_SPECCLR1] * DEFAULT_K_REFL;
814 }
815
816
817
818 static int stopX = -1;
819 static int stopY = -1;
820
PreShade(ShadeContext & sc,IReshadeFragment * pFrag)821 void MultiLayerShader::PreShade(ShadeContext& sc, IReshadeFragment* pFrag)
822 {
823 // Point3 U = sc.VectorFrom( Point3( 0.01f, 0.0f, 1.0f ), REF_OBJECT );
824 // U = Normalize( U );
825 Point3 T = GetTangent( sc, 0 );
826 pFrag->AddUnitVecChannel( T );
827 }
828
PostShade(ShadeContext & sc,IReshadeFragment * pFrag,int & nextTexIndex,IllumParams * ip)829 void MultiLayerShader::PostShade(ShadeContext& sc, IReshadeFragment* pFrag, int& nextTexIndex, IllumParams* ip)
830 {
831 Point3 T = pFrag->GetUnitVecChannel( nextTexIndex++ );
832 InternalIllum( sc, *ip, &T );
833 }
834
835
Illum(ShadeContext & sc,IllumParams & ip)836 void MultiLayerShader::Illum(ShadeContext &sc, IllumParams &ip)
837 {
838 InternalIllum( sc, ip, NULL );
839 }
840
InternalIllum(ShadeContext & sc,IllumParams & ip,Point3 * pTangent)841 void MultiLayerShader::InternalIllum(ShadeContext &sc, IllumParams &ip, Point3* pTangent )
842 {
843 LightDesc *l;
844 Color lightCol;
845
846 #ifdef _DEBUG
847 IPoint2 sp = sc.ScreenCoord();
848 if ( sp.x == stopX && sp.y == stopY )
849 sp.x = stopX;
850 #endif
851
852 for (int i=0; i<sc.nLights; i++) {
853 l = sc.Light(i);
854 float NL, kL;
855 Point3 L;
856 if (l->Illuminate( sc, sc.Normal(), lightCol, L, NL, kL)) {
857 if (l->ambientOnly) {
858 ip.ambIllumOut += lightCol;
859 continue;
860 }
861 if (NL<=0.0f)
862 continue;
863
864 // specular
865 Color spec(0.0f, 0.0f, 0.0f);
866 if (l->affectSpecular) {
867 Point3 T = (pTangent)? *pTangent : GetTangent( sc, 0 );
868 float g1 = GaussHighlight( ip.channels[_GL1].r, ip.channels[_AN1].r,
869 ip.channels[_OR1].r, sc.Normal(), sc.V(), L, T, &NL );
870
871 Color spec1 = g1 * kL * ip.channels[_SPECLEV1].r * ip.channels[_SPECCLR1] * lightCol;
872 //spec1 = Bound( spec1 );
873
874 float g2 = GaussHighlight( ip.channels[_GL2].r, ip.channels[_AN2].r,
875 ip.channels[_OR2].r, sc.Normal(), sc.V(), L, T, &NL );
876
877 Color spec2 = g2 * kL * ip.channels[_SPECLEV2].r * ip.channels[_SPECCLR2] * lightCol;
878
879 // composite spec1 over spec2
880 spec = spec1;
881 if (getUseComposite()) {
882 Color rem = 1.0f - Bound( spec1 );
883 spec += rem * spec2;
884 }
885 else {
886 spec += spec2;
887 }
888 ip.specIllumOut += spec;
889
890 } // end, affect specular
891
892 // diffuse
893 if (l->affectDiffuse){
894 // Color d = OrenNayarIllum( ip.N, L, -ip.V, ip.channels[_DIFFROUGH].r * Pi*0.5f, ip.channels[_DIFFCLR], NL );
895 // d = d * ip.channels[_DIFFLEV].r; // diff lev
896 // ip.diffIllumOut += kL * d * lightCol;
897 float diffIntens;
898 Color d = OrenNayarIllum( sc.Normal(), L, sc.V(), ip.channels[_DIFFROUGH].r * Pi*0.5f, ip.channels[_DIFFCLR], &diffIntens, NL );
899 d = d * ip.channels[_DIFFLEV].r;
900 ip.diffIllumOut += kL * d * lightCol;
901 ip.diffIllumIntens += kL * diffIntens * Intens(lightCol);
902 }
903
904 } // end, illuminated
905 } // for each light
906
907 // Apply mono self illumination
908 if ( ! selfIllumClrOn ){
909 float si = 0.3333333f * (ip.channels[_SI].r + ip.channels[_SI].g + ip.channels[_SI].b);
910 // float si = ip.channels[_SI].r;
911 if ( si > 0.0f ) {
912 if ( si >= 1.0f ) {
913 ip.selfIllumOut += ip.channels[_DIFFCLR];
914 ip.diffIllumOut = Color( 0.0f, 0.0f, 0.0f );
915 } else {
916 ip.selfIllumOut += si * ip.channels[_DIFFCLR];;
917 ip.diffIllumOut *= (1.0f - si); // * ip.channels[_DIFFCLR];
918 // fade the ambient down on si: 5/27/99 ke
919 ip.ambIllumOut *= 1.0f-si;
920 }
921 }
922 } else {
923 // colored self illum,
924 ip.selfIllumOut += ip.channels[_SI];
925 }
926
927 // now we can multiply by the clrs
928 ip.ambIllumOut *= ip.channels[_AMBCLR];
929
930 int chan = ip.stdIDToChannel[ ID_RR ];
931 ShadeTransmission(sc, ip, ip.channels[chan], ip.refractAmt);
932 chan = ip.stdIDToChannel[ ID_RL ];
933 ShadeReflection( sc, ip, ip.channels[chan] );
934
935 if (sc.globContext != NULL && sc.globContext->pToneOp != NULL) {
936 if (isInvertSelfIllum())
937 sc.globContext->pToneOp->RGBToScaled(ip.selfIllumOut);
938 if (isInvertReflect() && (ip.hasComponents & HAS_REFLECT))
939 sc.globContext->pToneOp->RGBToScaled(ip.reflIllumOut);
940 if (isInvertRefract() && (ip.hasComponents & HAS_REFRACT))
941 sc.globContext->pToneOp->RGBToScaled(ip.transIllumOut);
942 }
943
944 CombineComponents( sc, ip );
945
946 // get the diffuse intensity...unscramble the wavelength dependence
947 // float rho, diffIntens;
948 // rho = ip.channels[_DIFFCLR].r == 0.0f ? 1.0f : 1.0f / ip.channels[_DIFFCLR].r;
949 // diffIntens = ip.diffIllumOut.r * rho;
950 // rho = ip.channels[_DIFFCLR].g == 0.0f ? 1.0f : 1.0f / ip.channels[_DIFFCLR].g;
951 // diffIntens += ip.diffIllumOut.g * rho;
952 // rho = ip.channels[_DIFFCLR].b == 0.0f ? 1.0f : 1.0f / ip.channels[_DIFFCLR].b;
953 // diffIntens += ip.diffIllumOut.b * rho;
954 // ip.diffIllumIntens = diffIntens * 0.5f;
955 }
956
957
958
959 ///////////////////////// The dialog class //////////////////////////////////
960 class MultiLayerShaderDlg : public ShaderParamDlg {
961 public:
962 MultiLayerShader* pShader;
963 StdMat2* pMtl;
964 HPALETTE hOldPal;
965 HWND hwmEdit; // window handle of the materials editor dialog
966 IMtlParams* pMtlPar;
967 HWND hwHilite1; // the hilite windows
968 HWND hwHilite2;
969 HWND hRollup; // Rollup panel
970 TimeValue curTime;
971 BOOL valid;
972 BOOL isActive;
973
974 IColorSwatch *cs[MULTI_LAYER_NCOLBOX];
975 ISpinnerControl *lev1Spin, *gl1Spin, *an1Spin;
976 ISpinnerControl *lev2Spin, *gl2Spin, *an2Spin;
977 ISpinnerControl *dlevSpin, *droughSpin,*or1Spin, *or2Spin, *trSpin, *siSpin;
978 ICustButton* texMBut[MULTI_LAYER_NMBUTS];
979 TexDADMgr dadMgr;
980
981 MultiLayerShaderDlg( HWND hwMtlEdit, IMtlParams *pParams );
982 ~MultiLayerShaderDlg();
983
984 // required for correctly operating map buttons
FindSubTexFromHWND(HWND hw)985 int FindSubTexFromHWND(HWND hw) {
986 for (long i=0; i < MULTI_LAYER_NMBUTS; i++) {
987 if (hw == texMBut[i]->GetHwnd())
988 return texmapFromMBut[i];
989 }
990 return -1;
991 }
992
993 // Methods
994 INT_PTR PanelProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam );
ClassID()995 Class_ID ClassID(){ return MultiLayerShaderClassID; }
996
SetThing(ReferenceTarget * m)997 void SetThing(ReferenceTarget *m){ pMtl = (StdMat2*)m; }
SetThings(StdMat2 * theMtl,Shader * theShader)998 void SetThings( StdMat2* theMtl, Shader* theShader )
999 { if (pShader) pShader->SetParamDlg(NULL,0);
1000 pShader = (MultiLayerShader*)theShader;
1001 if(pShader) pShader->SetParamDlg(this,0);
1002 pMtl = theMtl;
1003 }
GetThing()1004 ReferenceTarget* GetThing(){ return pMtl; } // mtl is the thing! (for DAD!)
GetShader()1005 Shader* GetShader(){ return pShader; }
1006
SetTime(TimeValue t)1007 void SetTime(TimeValue t) {
1008 //DS 2/26/99: added interval test to prevent redrawing when not necessary
1009 curTime = t;
1010 if (!pShader->ivalid.InInterval(t)) {
1011 Interval v;
1012 pShader->Update(t,v);
1013 LoadDialog(TRUE);
1014 }
1015 }
KeyAtCurTime(int id)1016 BOOL KeyAtCurTime(int id) { return pShader->KeyAtTime(id,curTime); }
DeleteThis()1017 void DeleteThis() { delete this; }
ActivateDlg(BOOL dlgOn)1018 void ActivateDlg( BOOL dlgOn ){ isActive = dlgOn; }
GetHWnd()1019 HWND GetHWnd(){ return hRollup; }
NotifyChanged()1020 void NotifyChanged(){ pShader->NotifyChanged(); }
1021 void LoadDialog(BOOL draw);
ReloadDialog()1022 void ReloadDialog(){ Interval v; pShader->Update(pMtlPar->GetTime(), v); LoadDialog(FALSE);}
UpdateDialog(ParamID paramId)1023 void UpdateDialog( ParamID paramId ){ ReloadDialog(); }
1024
UpdateMtlDisplay()1025 void UpdateMtlDisplay(){ pMtlPar->MtlChanged(); } // redraw viewports
1026 void UpdateHilite( long nHilite );
1027 void UpdateColSwatches();
1028 void UpdateMapButtons();
1029 void UpdateOpacity();
1030 void SetLockADTex(BOOL lock);
1031 void SetLockAD(BOOL lock);
1032 void UpdateLockADTex( BOOL passOn);
1033
SelectEditColor(int i)1034 void SelectEditColor(int i) { cs[ i ]->EditThis(FALSE); }
1035 };
1036
MultiLayerShaderDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)1037 static INT_PTR CALLBACK MultiLayerShaderDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
1038 MultiLayerShaderDlg *theDlg;
1039 if (msg == WM_INITDIALOG) {
1040 theDlg = (MultiLayerShaderDlg*)lParam;
1041 DLSetWindowLongPtr(hwndDlg, lParam);
1042 } else {
1043 if ( (theDlg = DLGetWindowLongPtr<MultiLayerShaderDlg*>(hwndDlg) ) == NULL )
1044 return FALSE;
1045 }
1046 theDlg->isActive = 1;
1047 BOOL res = theDlg->PanelProc(hwndDlg, msg, wParam, lParam);
1048 theDlg->isActive = 0;
1049 return res;
1050 }
1051
1052
CreateParamDialog(HWND hOldRollup,HWND hwMtlEdit,IMtlParams * imp,StdMat2 * theMtl,int rollupOpen,int)1053 ShaderParamDlg* MultiLayerShader::CreateParamDialog(HWND hOldRollup, HWND hwMtlEdit, IMtlParams *imp, StdMat2* theMtl, int rollupOpen, int )
1054 {
1055 Interval v;
1056 Update(imp->GetTime(),v);
1057
1058 paramDlg = new MultiLayerShaderDlg(hwMtlEdit, imp);
1059 paramDlg->SetThings( theMtl, this );
1060 int rollupflags = rolloutOpen ? 0 : APPENDROLL_CLOSED;
1061
1062 LoadStdShaderResources();
1063 if ( hOldRollup ) {
1064 paramDlg->hRollup = imp->ReplaceRollupPage(
1065 hOldRollup,
1066 hInstance,
1067 MAKEINTRESOURCE(IDD_DMTL_BASIC_MULTILAYER1),
1068 MultiLayerShaderDlgProc,
1069 GetString(IDS_KE_MULTI_LAYER_BASIC), // your name here
1070 (LPARAM)paramDlg ,
1071 // NS: Bugfix 263414 keep the old category and store it for the current rollup
1072 rollupflags|ROLLUP_SAVECAT|ROLLUP_USEREPLACEDCAT
1073 );
1074 } else
1075 paramDlg->hRollup = imp->AddRollupPage(
1076 hInstance,
1077 MAKEINTRESOURCE(IDD_DMTL_BASIC_MULTILAYER1),
1078 MultiLayerShaderDlgProc,
1079 GetString(IDS_KE_MULTI_LAYER_BASIC),
1080 (LPARAM)paramDlg ,
1081 rollupflags
1082 );
1083
1084 return (ShaderParamDlg*)paramDlg;
1085 }
1086
NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget,PartID & partID,RefMessage message)1087 RefResult MultiLayerShader::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
1088 PartID& partID, RefMessage message )
1089 {
1090 switch (message) {
1091 case REFMSG_CHANGE:
1092 ivalid.SetEmpty();
1093 if (hTarget == pblock){
1094 // update UI if paramblock changed, possibly from scripter
1095 ParamID changingParam = pblock->LastNotifyParamID();
1096 // reload the dialog if present
1097 if (paramDlg){
1098 paramDlg->UpdateDialog( changingParam );
1099 }
1100 }
1101 break;
1102 }
1103 return(REF_SUCCEED);
1104 }
1105
1106
MultiLayerShaderDlg(HWND hwMtlEdit,IMtlParams * pParams)1107 MultiLayerShaderDlg::MultiLayerShaderDlg( HWND hwMtlEdit, IMtlParams *pParams)
1108 {
1109 pMtl = NULL;
1110 pShader = NULL;
1111 hwmEdit = hwMtlEdit;
1112 pMtlPar = pParams;
1113 dadMgr.Init(this);
1114 dlevSpin = droughSpin =lev1Spin = lev2Spin = gl1Spin = an1Spin =gl2Spin = an2Spin = NULL;
1115 or1Spin = or2Spin = trSpin = siSpin = NULL;
1116 hRollup = hwHilite1 = hwHilite2 =NULL;
1117 curTime = pMtlPar->GetTime();
1118
1119 isActive = valid = FALSE;
1120
1121 for( long i = 0; i < MULTI_LAYER_NCOLBOX; ++i )
1122 cs[ i ] = NULL;
1123
1124 for( long i = 0; i < MULTI_LAYER_NMBUTS; ++i )
1125 texMBut[ i ] = NULL;
1126 }
1127
~MultiLayerShaderDlg()1128 MultiLayerShaderDlg::~MultiLayerShaderDlg()
1129 {
1130 HDC hdc = GetDC(hRollup);
1131 GetGPort()->RestorePalette(hdc, hOldPal);
1132 ReleaseDC(hRollup, hdc);
1133
1134 if( pShader ) pShader->SetParamDlg(NULL,0);
1135
1136 for (long i=0; i < MULTI_LAYER_NMBUTS; i++ ){
1137 ReleaseICustButton( texMBut[i] );
1138 texMBut[i] = NULL;
1139 }
1140
1141 for (long i=0; i<MULTI_LAYER_NCOLBOX; i++)
1142 if (cs[i]) ReleaseIColorSwatch(cs[i]); // mjm - 5.10.99
1143
1144 ReleaseISpinner(dlevSpin);
1145 ReleaseISpinner(droughSpin);
1146 ReleaseISpinner(lev1Spin);
1147 ReleaseISpinner(lev2Spin);
1148 ReleaseISpinner(gl1Spin);
1149 ReleaseISpinner(an1Spin);
1150 ReleaseISpinner(gl2Spin);
1151 ReleaseISpinner(an2Spin);
1152 ReleaseISpinner(or1Spin);
1153 ReleaseISpinner(or2Spin);
1154 ReleaseISpinner(trSpin);
1155 ReleaseISpinner(siSpin);
1156
1157 DLSetWindowLongPtr(hRollup, NULL);
1158 DLSetWindowLongPtr(hwHilite1, NULL);
1159 DLSetWindowLongPtr(hwHilite2, NULL);
1160
1161 if(pShader){
1162 IRollupWindow* pRollup = pMtlPar->GetMtlEditorRollup();
1163 pShader->SetPanelOpen(pRollup->IsPanelOpen(pRollup->GetPanelIndex(hRollup)));
1164 }
1165
1166 hwHilite1 = hwHilite2 = hRollup = NULL;
1167 }
1168
1169
LoadDialog(BOOL draw)1170 void MultiLayerShaderDlg::LoadDialog(BOOL draw)
1171 {
1172 if (pShader && hRollup) {
1173 dlevSpin->SetValue(FracToPc(pShader->GetDiffuseLevel(0,0)),FALSE);
1174 dlevSpin->SetKeyBrackets(KeyAtCurTime(ml_diffuse_level));
1175 droughSpin->SetValue(FracToPc(pShader->GetDiffuseRough(0,0)),FALSE);
1176 droughSpin->SetKeyBrackets(KeyAtCurTime(ml_diffuse_rough));
1177 lev1Spin->SetValue(FracToPc(pShader->GetSpecLevel1(0,0)),FALSE);
1178 lev1Spin->SetKeyBrackets(KeyAtCurTime(ml_specular_level1));
1179 lev2Spin->SetValue(FracToPc(pShader->GetSpecLevel2(0,0)),FALSE);
1180 lev2Spin->SetKeyBrackets(KeyAtCurTime(ml_specular_level2));
1181
1182 gl1Spin->SetValue( FracToPc(pShader->GetGlossiness1(0,0)), FALSE);
1183 gl1Spin->SetKeyBrackets(KeyAtCurTime(ml_glossiness1));
1184 gl2Spin->SetValue( FracToPc(pShader->GetGlossiness2(0,0)), FALSE);
1185 gl2Spin->SetKeyBrackets(KeyAtCurTime(ml_glossiness2));
1186
1187 an1Spin->SetValue( FracToPc(pShader->GetAnisotropy1(0,0)), FALSE);
1188 an1Spin->SetKeyBrackets(KeyAtCurTime(ml_anisotropy1));
1189 an2Spin->SetValue( FracToPc(pShader->GetAnisotropy2(0,0)), FALSE);
1190 an2Spin->SetKeyBrackets(KeyAtCurTime(ml_anisotropy2));
1191
1192 or1Spin->SetValue( FracToPc(pShader->GetOrientation1(0,0)), FALSE);
1193 or1Spin->SetKeyBrackets(KeyAtCurTime(ml_orientation1));
1194 or2Spin->SetValue( FracToPc(pShader->GetOrientation2(0,0)), FALSE);
1195 or2Spin->SetKeyBrackets(KeyAtCurTime(ml_orientation2));
1196
1197 trSpin->SetValue(FracToPc(pMtl->GetOpacity( curTime )),FALSE);
1198 trSpin->SetKeyBrackets(pMtl->KeyAtTime(OPACITY_PARAM, curTime));
1199
1200 // color selfIllum
1201 BOOL colorSelfIllum = pShader->IsSelfIllumClrOn();
1202 SetCheckBox(hRollup,IDC_SI_COLORON, colorSelfIllum );
1203 if( colorSelfIllum ) {
1204 // ShowWindow( siSpin->GetHwnd(), SW_HIDE );
1205 ShowWindow( GetDlgItem(hRollup, IDC_SI_EDIT), SW_HIDE );
1206 ShowWindow( GetDlgItem(hRollup, IDC_SI_SPIN), SW_HIDE );
1207 ShowWindow( cs[N_SI_CLR]->GetHwnd(), SW_SHOW );
1208 } else {
1209 // disable the color swatch
1210 ShowWindow( cs[N_SI_CLR]->GetHwnd(), SW_HIDE );
1211 // show self-illum slider
1212 // ShowWindow( siSpin->GetHwnd(), SW_SHOW );
1213 ShowWindow( GetDlgItem(hRollup, IDC_SI_EDIT), SW_SHOW );
1214 ShowWindow( GetDlgItem(hRollup, IDC_SI_SPIN), SW_SHOW );
1215
1216 siSpin->SetValue(FracToPc(pShader->GetSelfIllum(0,0)), FALSE);
1217 siSpin->SetKeyBrackets(KeyAtCurTime(ml_self_illum_amnt));
1218 }
1219 CheckButton(hRollup, IDC_LOCK_AD, pShader->GetLockAD() );
1220
1221 UpdateLockADTex( 0 );
1222 UpdateColSwatches();
1223 UpdateHilite2( hwHilite1, pShader, 1 );
1224 UpdateHilite2( hwHilite2, pShader, 2 );
1225 }
1226 }
1227
1228
1229
1230 static TCHAR* mapStates[] = { _T(" "), _T("m"), _T("M") };
1231
UpdateMapButtons()1232 void MultiLayerShaderDlg::UpdateMapButtons()
1233 {
1234
1235 for ( long i = 0; i < MULTI_LAYER_NMBUTS; ++i ) {
1236 int nMap = texmapFromMBut[ i ];
1237 int state = pMtl->GetMapState( nMap );
1238 texMBut[i]->SetText( mapStates[ state ] );
1239
1240 TSTR nm = pMtl->GetMapName( nMap );
1241 texMBut[i]->SetTooltip(TRUE, nm);
1242 }
1243 }
1244
1245
UpdateOpacity()1246 void MultiLayerShaderDlg::UpdateOpacity()
1247 {
1248 trSpin->SetValue(FracToPc(pMtl->GetOpacity(curTime)),FALSE);
1249 trSpin->SetKeyBrackets(pMtl->KeyAtTime(OPACITY_PARAM, curTime));
1250 }
1251
1252
UpdateColSwatches()1253 void MultiLayerShaderDlg::UpdateColSwatches()
1254 {
1255 cs[0]->SetColor( pShader->GetAmbientClr( curTime ) );
1256 cs[0]->SetKeyBrackets( pShader->KeyAtTime(ml_ambient, curTime) );
1257
1258 cs[1]->SetColor( pShader->GetDiffuseClr( curTime ) );
1259 cs[1]->SetKeyBrackets( pShader->KeyAtTime(ml_diffuse, curTime) );
1260
1261 cs[2]->SetColor( pShader->GetSelfIllumClr( curTime ) );
1262 cs[2]->SetKeyBrackets( pShader->KeyAtTime(ml_self_illum_color, curTime) );
1263
1264 cs[3]->SetColor( pShader->GetSpecColor1( curTime ) );
1265 cs[3]->SetKeyBrackets( pShader->KeyAtTime(ml_specular1, curTime) );
1266
1267 cs[4]->SetColor( pShader->GetSpecColor2( curTime ) );
1268 cs[4]->SetKeyBrackets( pShader->KeyAtTime(ml_specular2, curTime) );
1269 }
1270
SetLockAD(BOOL lock)1271 void MultiLayerShaderDlg::SetLockAD(BOOL lock)
1272 {
1273 if (lock) {
1274 if (IDYES!=MessageBox(hwmEdit, GetString(IDS_DS_LOCKAD), GetString(IDS_DS_LOCKCOL), MB_YESNO)) {
1275 CheckButton(hRollup, IDC_LOCK_AD, FALSE);
1276 return;
1277 }
1278 // set ambient color to diffuse
1279 pShader->SetAmbientClr( pShader->GetDiffuseClr(0,0), 0 );
1280 UpdateColSwatches();
1281 }
1282 pShader->SetLockAD(lock);
1283 }
1284
1285
UpdateLockADTex(BOOL passOn)1286 void MultiLayerShaderDlg::UpdateLockADTex( BOOL passOn)
1287 {
1288 int lock = pShader->GetLockADTex();
1289 CheckButton(hRollup, IDC_LOCK_ADTEX, lock);
1290
1291 ShowWindow(GetDlgItem(hRollup, IDC_MAPON_AM), !lock);
1292 texMBut[ 0 ]->Enable(!lock);
1293
1294 if ( passOn ) {
1295 pMtl->SyncADTexLock( lock );
1296 }
1297 // UpdateMtlDisplay();
1298 }
1299
SetLockADTex(BOOL lock)1300 void MultiLayerShaderDlg::SetLockADTex(BOOL lock)
1301 {
1302 pShader->SetLockADTex( lock );
1303 UpdateLockADTex(TRUE); // passon to mtl
1304 // UpdateMtlDisplay();
1305 }
1306
1307
ColorIDCToIndex(int idc)1308 static int ColorIDCToIndex(int idc) {
1309 switch (idc) {
1310 case IDC_AMB_CLR: return 0;
1311 case IDC_DIFF_CLR: return 1;
1312 case IDC_SI_CLR: return 2;
1313 case IDC_SPEC_CLR1: return 3;
1314 case IDC_SPEC_CLR2: return 4;
1315 default: return 0;
1316 }
1317 }
1318
1319
PanelProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)1320 INT_PTR MultiLayerShaderDlg::PanelProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam )
1321 {
1322 int id = LOWORD(wParam);
1323 int code = HIWORD(wParam);
1324 switch (msg) {
1325 case WM_INITDIALOG:
1326 {
1327 HDC theHDC = GetDC(hwndDlg);
1328 hOldPal = GetGPort()->PlugPalette(theHDC);
1329 ReleaseDC(hwndDlg,theHDC);
1330
1331 cs[0] = GetIColorSwatch(GetDlgItem(hwndDlg, IDC_AMB_CLR),
1332 pShader->GetAmbientClr(0,0), GetString(IDS_DS_AMBIENT) );
1333
1334 cs[1] = GetIColorSwatch(GetDlgItem(hwndDlg, IDC_DIFF_CLR),
1335 pShader->GetDiffuseClr(0,0), GetString(IDS_DS_DIFFUSE) );
1336
1337 cs[2] = GetIColorSwatch(GetDlgItem(hwndDlg, IDC_SI_CLR),
1338 pShader->GetSelfIllumClr(0,0), GetString(IDS_KE_SELFILLUM_CLR) );
1339
1340 cs[3] = GetIColorSwatch(GetDlgItem(hwndDlg, IDC_SPEC_CLR1),
1341 pShader->GetSpecColor1(0,0), GetString(IDS_KE_SPEC_CLR1) );
1342
1343 cs[4] = GetIColorSwatch(GetDlgItem(hwndDlg, IDC_SPEC_CLR2),
1344 pShader->GetSpecColor2(0,0), GetString(IDS_KE_SPEC_CLR2) );
1345
1346
1347 hwHilite1 = GetDlgItem(hwndDlg, IDC_HIGHLIGHT1 );
1348 DLSetWindowLongPtr( hwHilite1, Hilite2Layer1WndProc);
1349 hwHilite2 = GetDlgItem(hwndDlg, IDC_HIGHLIGHT2 );
1350 DLSetWindowLongPtr( hwHilite2, Hilite2Layer2WndProc);
1351
1352 dlevSpin = SetupIntSpinner(hwndDlg, IDC_DIFFLEV_SPIN, IDC_DIFFLEV_EDIT, 0,400, 0);
1353 droughSpin = SetupIntSpinner(hwndDlg, IDC_DIFFROUGH_SPIN, IDC_DIFFROUGH_EDIT, 0,100, 0);
1354 lev1Spin = SetupIntSpinner(hwndDlg, IDC_SPEC_LEV1_SPIN, IDC_SPEC_LEV1_EDIT, 0,999, 0);
1355 gl1Spin = SetupIntSpinner(hwndDlg, IDC_GL1_SPIN, IDC_GL1_EDIT, 0,100, 0);
1356 an1Spin = SetupIntSpinner(hwndDlg, IDC_AN1_SPIN, IDC_AN1_EDIT, 0,100, 0);
1357
1358 lev2Spin = SetupIntSpinner(hwndDlg, IDC_SPEC_LEV2_SPIN, IDC_SPEC_LEV2_EDIT, 0, 999, 0);
1359 gl2Spin = SetupIntSpinner(hwndDlg, IDC_GL2_SPIN, IDC_GL2_EDIT, 0,100, 0);
1360 an2Spin = SetupIntSpinner(hwndDlg, IDC_AN2_SPIN, IDC_AN2_EDIT, 0,100, 0);
1361
1362 or1Spin = SetupIntSpinner(hwndDlg, IDC_OR1_SPIN, IDC_OR1_EDIT, -9999, 9999, 0);
1363 or2Spin = SetupIntSpinner(hwndDlg, IDC_OR2_SPIN, IDC_OR2_EDIT, -9999, 9999, 0);
1364 trSpin = SetupIntSpinner(hwndDlg, IDC_TR_SPIN, IDC_TR_EDIT, 0,100, 0);
1365 siSpin = SetupIntSpinner(hwndDlg, IDC_SI_SPIN, IDC_SI_EDIT, 0,100, 0);
1366
1367 if( pShader->IsSelfIllumClrOn() ) {
1368 // enable the color swatch, disable the spinner
1369 ShowWindow( GetDlgItem(hwndDlg, IDC_SI_EDIT), SW_HIDE );
1370 ShowWindow( GetDlgItem(hwndDlg, IDC_SI_SPIN), SW_HIDE );
1371 } else {
1372 // disable the color swatch
1373 ShowWindow( cs[N_SI_CLR]->GetHwnd(), SW_HIDE );
1374 }
1375
1376 for (int j=0; j < MULTI_LAYER_NMBUTS; j++) {
1377 texMBut[j] = GetICustButton(GetDlgItem(hwndDlg,texMButtonsIDC[j]));
1378 assert( texMBut[j] );
1379 texMBut[j]->SetRightClickNotify(TRUE);
1380 texMBut[j]->SetDADMgr(&dadMgr);
1381 }
1382
1383 SetupLockButton(hwndDlg,IDC_LOCK_AD,FALSE);
1384 SetupPadLockButton(hwndDlg,IDC_LOCK_ADTEX, TRUE);
1385
1386 LoadDialog(TRUE);
1387 }
1388 break;
1389
1390 case WM_COMMAND:
1391 {
1392 for ( int i=0; i < MULTI_LAYER_NMBUTS; i++) {
1393 if (id == texMButtonsIDC[i]) {
1394 PostMessage(hwmEdit,WM_TEXMAP_BUTTON, texmapFromMBut[i],(LPARAM)pMtl );
1395 UpdateMapButtons();
1396 goto exit;
1397 }
1398 }
1399 }
1400 switch (id) {
1401
1402 case IDC_LOCK_AD:
1403 SetLockAD(IsButtonChecked(hwndDlg, IDC_LOCK_AD));
1404 UpdateMtlDisplay();
1405 break;
1406
1407 case IDC_LOCK_ADTEX:{
1408 BOOL on = IsButtonChecked(hwndDlg, IDC_LOCK_ADTEX);
1409 SetLockADTex(on);
1410 UpdateMtlDisplay();
1411 } break;
1412
1413 case IDC_SI_COLORON:{
1414 int isOn = GetCheckBox(hwndDlg, IDC_SI_COLORON );
1415 pShader->SetSelfIllumClrOn( isOn );
1416 if ( isOn ) {
1417 // enable the color swatch, disable the spinner
1418 ShowWindow( GetDlgItem(hwndDlg, IDC_SI_EDIT), SW_HIDE );
1419 ShowWindow( GetDlgItem(hwndDlg, IDC_SI_SPIN), SW_HIDE );
1420 ShowWindow( cs[N_SI_CLR]->GetHwnd(), SW_SHOW );
1421 } else {
1422 // disable the color swatch
1423 ShowWindow( cs[N_SI_CLR]->GetHwnd(), SW_HIDE );
1424 ShowWindow( GetDlgItem(hwndDlg, IDC_SI_EDIT), SW_SHOW );
1425 ShowWindow( GetDlgItem(hwndDlg, IDC_SI_SPIN), SW_SHOW );
1426 }
1427 NotifyChanged();
1428 // UpdateMtlDisplay();
1429 }
1430 break;
1431
1432 }
1433 break;
1434 case CC_COLOR_SEL: {
1435 int id = LOWORD(wParam);
1436 SelectEditColor(ColorIDCToIndex(id));
1437 }
1438 break;
1439 case CC_COLOR_DROP: {
1440 int id = LOWORD(wParam);
1441 SelectEditColor(ColorIDCToIndex(id));
1442 UpdateMtlDisplay();
1443 }
1444 break;
1445 case CC_COLOR_BUTTONDOWN:
1446 theHold.Begin();
1447 break;
1448 case CC_COLOR_BUTTONUP:
1449 if (HIWORD(wParam)) theHold.Accept(GetString(IDS_DS_PARAMCHG));
1450 else theHold.Cancel();
1451 UpdateMtlDisplay();
1452 break;
1453 case CC_COLOR_CHANGE: {
1454 int id = LOWORD(wParam);
1455 int buttonUp = HIWORD(wParam);
1456 int n = ColorIDCToIndex(id);
1457 if (buttonUp) theHold.Begin();
1458 Color curColor(cs[n]->GetColor());
1459 switch ( n ) {
1460 case 0: pShader->SetAmbientClr( curColor, curTime );
1461 if ( pShader->GetLockAD() )
1462 pShader->SetDiffuseClr(curColor, curTime);
1463 break;
1464 case 1: pShader->SetDiffuseClr( curColor, curTime );
1465 if ( pShader->GetLockAD() )
1466 pShader->SetAmbientClr( curColor, curTime );
1467 break;
1468 case 2: pShader->SetSelfIllumClr( curColor, curTime ); break;
1469 case 3: pShader->SetSpecColor1( curColor, curTime ); break;
1470 case 4: pShader->SetSpecColor2( curColor, curTime ); break;
1471 }
1472 if (buttonUp) {
1473 theHold.Accept(GetString(IDS_DS_PARAMCHG));
1474 NotifyChanged();
1475 // DS: 5/11/99- this was commented out. I put it back in, because
1476 // it is necessary for the Reset button in the color picker to
1477 // update the viewport.
1478 UpdateMtlDisplay();
1479 }
1480 } break;
1481 case WM_PAINT:
1482 if (!valid) {
1483 valid = TRUE;
1484 ReloadDialog();
1485 }
1486 return FALSE;
1487 case WM_CLOSE:
1488 case WM_DESTROY:
1489 break;
1490 case CC_SPINNER_CHANGE:
1491 if (!theHold.Holding()) theHold.Begin();
1492 switch (id) {
1493 case IDC_DIFFLEV_SPIN:
1494 pShader->SetDiffuseLevel( PcToFrac( dlevSpin->GetIVal() ), curTime );
1495 break;
1496 case IDC_DIFFROUGH_SPIN:
1497 pShader->SetDiffuseRough( PcToFrac( droughSpin->GetIVal() ), curTime );
1498 break;
1499 case IDC_SPEC_LEV1_SPIN:
1500 pShader->SetSpecLevel1( PcToFrac( lev1Spin->GetIVal() ), curTime );
1501 UpdateHilite2( hwHilite1, pShader, 1 );
1502 break;
1503 case IDC_GL1_SPIN:
1504 pShader->SetGlossiness1( PcToFrac( gl1Spin->GetIVal() ), curTime );
1505 UpdateHilite2( hwHilite1, pShader, 1 );
1506 break;
1507 case IDC_AN1_SPIN:
1508 pShader->SetAnisotropy1( PcToFrac( an1Spin->GetIVal() ), curTime );
1509 UpdateHilite2( hwHilite1, pShader, 1 );
1510 break;
1511
1512 case IDC_GL2_SPIN:
1513 pShader->SetGlossiness2( PcToFrac( gl2Spin->GetIVal() ), curTime );
1514 UpdateHilite2( hwHilite2, pShader, 2 );
1515 break;
1516 case IDC_AN2_SPIN:
1517 pShader->SetAnisotropy2( PcToFrac( an2Spin->GetIVal() ), curTime );
1518 UpdateHilite2( hwHilite2, pShader, 2 );
1519 break;
1520 case IDC_SPEC_LEV2_SPIN:
1521 pShader->SetSpecLevel2( PcToFrac( lev2Spin->GetIVal() ), curTime );
1522 UpdateHilite2( hwHilite2, pShader, 2 );
1523 break;
1524
1525 case IDC_OR1_SPIN:
1526 pShader->SetOrientation1( PcToFrac(or1Spin->GetIVal()), curTime );
1527 break;
1528 case IDC_OR2_SPIN:
1529 pShader->SetOrientation2( PcToFrac(or2Spin->GetIVal()), curTime );
1530 break;
1531 case IDC_SI_SPIN:
1532 pShader->SetSelfIllum(PcToFrac(siSpin->GetIVal()),curTime);
1533 break;
1534 //***** >>>><<<< required handling for opacity....must be present in all dialogs
1535 case IDC_TR_SPIN:
1536 pMtl->SetOpacity(PcToFrac( trSpin->GetIVal()),curTime);
1537 break;
1538 }
1539 // UpdateMtlDisplay();
1540 break;
1541
1542 case CC_SPINNER_BUTTONDOWN:
1543 theHold.Begin();
1544 break;
1545
1546 case WM_CUSTEDIT_ENTER:
1547 case CC_SPINNER_BUTTONUP:
1548 if (HIWORD(wParam) || msg==WM_CUSTEDIT_ENTER)
1549 theHold.Accept(GetString(IDS_DS_PARAMCHG));
1550 else
1551 theHold.Cancel();
1552 UpdateMtlDisplay();
1553 break;
1554
1555 }
1556 exit:
1557 return FALSE;
1558 }
1559
1560
1561