1 #include "stdafx.h"
2 #pragma hdrstop
3
4 #include "..\material\GameMaterial.h"
5 #include "..\material\BlenderListLoader.h"
6
7 #include "macrorec.h"
8
9 class XRayMtlClassDesc:public ClassDesc2 {
10 public:
IsPublic()11 int IsPublic () { return 1; }
Create(BOOL loading)12 void * Create (BOOL loading) { return new XRayMtl(loading); }
ClassName()13 const TCHAR * ClassName () { return GetString(IDS_CLASS_NAME); }
SuperClassID()14 SClass_ID SuperClassID () { return MATERIAL_CLASS_ID; }
ClassID()15 Class_ID ClassID () { return XRAYMTL_CLASS_ID; }
Category()16 const TCHAR* Category () { return GetString(IDS_CATEGORY); }
17 // JBW: new descriptor data accessors added. Note that the
18 // internal name is hardwired since it must not be localized.
InternalName()19 const TCHAR* InternalName () { return _T("S.T.A.L.K.E.R.Mtl"); } // returns fixed parsable name (scripter-visible name)
HInstance()20 HINSTANCE HInstance () { return hInstance; } // returns owning module handle
21 };
22
23 static XRayMtlClassDesc stdmtl2CD;
GetXRayMtlDesc()24 ClassDesc2* GetXRayMtlDesc() { return &stdmtl2CD; }
25
26 ShaderParamDlg* XRayMtl::pShaderDlg;
27 IAutoMParamDlg* XRayMtl::xrayDlg;
28 IAutoMParamDlg* XRayMtl::masterDlg;
29 IAutoMParamDlg* XRayMtl::texmapDlg;
30 IAutoMParamDlg* XRayMtl::extendedDlg;
31 IAutoMParamDlg* XRayMtl::samplingDlg;
32 HWND XRayMtl::curHwmEdit;
33 IMtlParams* XRayMtl::curImp;
34 Tab<ClassDesc*> XRayMtl::shaderList;
35 Tab<ClassDesc*> XRayMtl::samplerList;
36 LPSTR_vec XRayMtl::EShaders;
37 LPSTR_vec XRayMtl::CShaders;
38 LPSTR_vec XRayMtl::GameMtls;
39
40 /////////////////////////////////////////////////////////////////////////
41 // utility function
Min(float a,float b)42 IC float Min( float a, float b ) { return (a < b) ? a : b; }
Min(float a,float b,float c)43 IC float Min( float a, float b, float c ) { return (a < b) ? Min(a,c) : Min(b,c); }
Min(Color & c)44 IC float Min( Color& c ){ return Min( c.r, c.g, c.b ); }
Max(float a,float b)45 IC float Max( float a, float b ) { return (a < b) ? b : a; }
Max(float a,float b,float c)46 IC float Max( float a, float b, float c ) { return (a < b) ? Max( b, c ) : Max(a,c); }
Max(Color & c)47 IC float Max( Color& c ){ return Max( c.r, c.g, c.b ); }
48
LBound(float x,float min=0.0f)49 IC float LBound( float x, float min = 0.0f ){ return x < min ? min : x; }
LBound(Color & c,float min=0.0f)50 IC Color LBound( Color& c, float min = 0.0f )
51 { return Color( LBound(c.r, min), LBound(c.g, min), LBound(c.b, min) ); }
UBound(float x,float max=1.0f)52 IC float UBound( float x, float max = 1.0f ){ return x > max ? max : x; }
UBound(Color & c,float max=1.0f)53 IC Color UBound( Color& c, float max = 1.0f )
54 { return Color( UBound(c.r,max), UBound(c.g,max), UBound(c.b,max) ); }
55
Bound(float x,float min=0.0f,float max=1.0f)56 IC float Bound( float x, float min = 0.0f, float max = 1.0f ){ return x < min? min:( x > max? max : x); }
Bound(Color & c,float min=0.0f,float max=1.0f)57 IC Color Bound( Color& c, float min = 0.0f, float max = 1.0f ){
58 return Color( Bound(c.r,min,max), Bound(c.r,min,max), Bound(c.r,min,max) );
59 }
BoundInPlace(AColor & c,float min=0.0f,float max=1.0f)60 IC void BoundInPlace( AColor& c , float min = 0.0f, float max = 1.0f ){
61 if( c.r > max ) c.r = max; else if( c.r < min ) c.r = min;
62 if( c.g > max ) c.g = max; else if( c.g < min ) c.g = min;
63 if( c.b > max ) c.b = max; else if( c.b < min ) c.b = min;
64 if( c.a > max ) c.a = max; else if( c.a < min ) c.a = min;
65 }
66 /////////////////////////////////////////////////////////////////////////
67
68 /////////////////////////////////////////////////////////////////////////
69 // Material Texture Channels
70 //
71 #define MTL_NTEXMAPS 4
72
73
74 // channels ids needed by shader
75 #define _BUMP 0
76 #define _REFLECT 1
77 #define _REFRACT 2
78 #define _DISPLACE 3
79
80 // channel names
81 static int mtlChannelNameIDS[] = {
82 IDS_DS_BU, IDS_DS_RL, IDS_DS_RR, IDS_DS_DP,
83 };
84
85 // what channel corresponds to the stdMat ID's
86 static int mtlStdIDToChannel[N_ID_CHANNELS] = { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3 };
87
88 // internal non-local parsable channel map names
89 static TCHAR* mtlChannelInternalNames[STD2_NMAX_TEXMAPS] = {
90 _T("bumpMap"), _T("reflectionMap"), _T("refractionMap"), _T("displacementMap"),
91 _T(""), _T(""), _T(""), _T(""),
92
93 _T(""), _T(""), _T(""), _T(""),
94 _T(""), _T(""), _T(""), _T(""),
95
96 _T(""), _T(""), _T(""), _T(""),
97 _T(""), _T(""), _T(""), _T(""),
98 };
99
100 // sized for nmax textures
101 static int mtlChannelType[STD2_NMAX_TEXMAPS] = {
102 BUMP_CHANNEL, REFL_CHANNEL, REFR_CHANNEL, DISP_CHANNEL,
103 UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL,
104
105 UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL,
106 UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL,
107 UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL,
108 UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL, UNSUPPORTED_CHANNEL,
109 };
110
111
112 static IReshading::ReshadeRequirements chooseReshade[3][3] = {
113 { IReshading::RR_None,
114 IReshading::RR_NeedPreshade,
115 IReshading::RR_NeedReshade }, // RR_None
116 { IReshading::RR_NeedPreshade,
117 IReshading::RR_NeedPreshade,
118 IReshading::RR_NeedPreshade }, // RR_NeedPreshade
119 { IReshading::RR_NeedReshade,
120 IReshading::RR_NeedPreshade,
121 IReshading::RR_NeedReshade }, // RR_NeedReshade
122 };
123
124 #define NO_UPDATE -2
125
126 // parameter setter callback, reflect any ParamBlock-mediated param setting in instance data members.
127 // Since standard2 keeps many parameters as instance data members, these setter callbacks
128 // are implemented to reduce changes to existing code
129
130 class ShaderPBAccessor : public PBAccessor
131 {
132 public:
Set(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t)133 void Set(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t) // set from v
134 {
135 XRayMtl* m = (XRayMtl*)owner;
136 switch (id)
137 {
138 // use item data to unscramble sorted lists
139 case std2_shader_type: {
140 ClassDesc* pCD = XRayMtl::GetShaderCD(v.i);
141 if (pCD && m->GetShaderIndx() != NO_UPDATE )
142 {
143 m->SwitchShader(pCD);
144 m->shaderId = v.i;
145 }
146 } break;
147 case std2_shader_by_name: {
148 for (int i = 0; i < XRayMtl::NumShaders(); i++)
149 {
150 ClassDesc* pCD = XRayMtl::GetShaderCD(i);
151 if (_tcsicmp(pCD->ClassName(), v.s) == 0)
152 {
153 m->pb_shader->SetValue(std2_shader_type, 0, i);
154 break;
155 }
156 }
157 } break;
158 case std2_wire:
159 m->SetFlag(NEWSTDMTL_WIRE, v.i); break;
160 case std2_two_sided:
161 m->SetFlag(NEWSTDMTL_2SIDE, v.i); break;
162 case std2_face_map:
163 m->SetFlag(NEWSTDMTL_FACEMAP, v.i); break;
164 case std2_faceted:
165 m->SetFlag(NEWSTDMTL_FACETED, v.i); break;
166 }
167 }
168
Get(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t,Interval & valid)169 void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval& valid) // get into v
170 {
171 XRayMtl* m = (XRayMtl*)owner;
172 switch (id)
173 {
174 case std2_shader_by_name: {
175 ClassDesc* pCD = XRayMtl::GetShaderCD(m->shaderId);
176 if (pCD)
177 v.s = (TCHAR*)pCD->ClassName();
178 } break;
179 }
180 }
181 };
182 static ShaderPBAccessor shaderPBAccessor;
183
184 // shader rollout dialog proc
185 class ShaderDlgProc : public ParamMap2UserDlgProc
186 {
187 public:
DlgProc(TimeValue t,IParamMap2 * map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)188 BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
189 {
190 switch (msg)
191 {
192 case WM_INITDIALOG:
193 // load the shader dropdown
194 HWND hwndShader = GetDlgItem(hWnd, IDC_SHADER);
195 SendMessage(hwndShader, CB_RESETCONTENT, 0L, 0L);
196 for (int i = 0; i < XRayMtl::NumShaders(); i++) {
197 ClassDesc* pClassD = XRayMtl::GetShaderCD(i);
198 int n = SendMessage(hwndShader, CB_ADDSTRING, 0L, (LPARAM)(pClassD->ClassName()) );
199 SendMessage(hwndShader, CB_SETITEMDATA, n, (LPARAM)pClassD );
200 }
201 return TRUE;
202 }
203 return FALSE;
204 }
DeleteThis()205 void DeleteThis() { }
206 };
207
208
209 static ShaderDlgProc shaderDlgProc;
210
211 // shader parameters
212 static ParamBlockDesc2 std2_shader_blk ( std2_shader, _T("newShaderParameters"), 0, &stdmtl2CD, P_AUTO_CONSTRUCT + P_AUTO_UI, SHADER_PB_REF,
213 //rollout
214 IDD_DMTL_SHADER4, IDS_KE_SHADER, 0, 0, &shaderDlgProc,
215 // params
216 std2_shader_type, _T("shaderType"), TYPE_INT, 0, IDS_JW_SHADERTYPE,
217 p_default, 3,
218 p_ui, TYPE_INTLISTBOX, IDC_SHADER, 0,
219 p_accessor, &shaderPBAccessor,
220 end,
221 std2_wire, _T("wire"), TYPE_BOOL, 0, IDS_DS_WIREFRAME,
222 p_default, FALSE,
223 p_ui, TYPE_SINGLECHEKBOX, IDC_WIRE,
224 p_accessor, &shaderPBAccessor,
225 end,
226 std2_two_sided, _T("twoSided"), TYPE_BOOL, 0, IDS_JW_TWOSIDED,
227 p_default, FALSE,
228 p_ui, TYPE_SINGLECHEKBOX, IDC_2SIDE,
229 p_accessor, &shaderPBAccessor,
230 end,
231 std2_face_map, _T("faceMap"), TYPE_BOOL, 0, IDS_JW_FACEMAP,
232 p_default, FALSE,
233 p_ui, TYPE_SINGLECHEKBOX, IDC_FACE_MAP,
234 p_accessor, &shaderPBAccessor,
235 end,
236 std2_faceted, _T("faceted"), TYPE_BOOL, 0, IDS_KE_FACETED,
237 p_default, FALSE,
238 p_ui, TYPE_SINGLECHEKBOX, IDC_FACETED,
239 p_accessor, &shaderPBAccessor,
240 end,
241 std2_shader_by_name, _T("shaderByName"), TYPE_STRING, 0, IDS_JW_SHADERBYNAME,
242 p_accessor, &shaderPBAccessor,
243 end,
244 end
245 );
246
247 ////////////////////////
248 // Extended Rollout
249 class ExtendedPBAccessor : public PBAccessor
250 {
251 public:
Set(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t)252 void Set(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t) // set from v
253 {
254 XRayMtl* m = (XRayMtl*)owner;
255 IParamMap2* map = m->pb_extended ? m->pb_extended->GetMap() : NULL;
256
257 switch (id)
258 {
259 case std2_opacity_type:
260 m->SetFlag(NEWSTDMTL_ADD_TRANSP, v.i == 2);
261 m->SetFlag(NEWSTDMTL_FILT_TRANSP, v.i == 0);
262 if (map != NULL)
263 {
264 map->Show(std2_filter_color, v.i == 0);
265 map->Show(std2_ep_filter_map, v.i == 0);
266 m->UpdateTexmaps();
267 m->UpdateLockADTex(FALSE);
268 }
269 break;
270 case std2_opacity:
271 m->opacity = v.f;
272 if (m->pShader->GetParamDlg())
273 m->pShader->GetParamDlg()->UpdateOpacity();
274 break;
275 case std2_filter_color:
276 m->filter = *v.p; break;
277 case std2_falloff_type:
278 m->SetFlag(NEWSTDMTL_FALLOFF_OUT, v.i == 1); break;
279 case std2_falloff_amnt:
280 m->opfall = v.f; break;
281 case std2_ior:
282 m->ioRefract = v.f; break;
283
284 case std2_wire_size:
285 m->wireSize = v.f; break;
286 case std2_wire_units:
287 m->SetFlag(NEWSTDMTL_WIRE_UNITS, v.i == 1); break;
288
289 case std2_apply_refl_dimming:
290 m->dimReflect = v.i; break;
291 case std2_dim_lvl:
292 m->dimIntens = v.f; break;
293 case std2_refl_lvl:
294 m->dimMult = v.f; break;
295 }
296 }
297 };
298
299 static ExtendedPBAccessor extendedPBAccessor;
300
301 // extra rollout dialog proc
302 class ExtraDlgProc : public ParamMap2UserDlgProc
303 {
304 public:
DlgProc(TimeValue t,IParamMap2 * map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)305 BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
306 {
307 switch (msg)
308 {
309 case WM_INITDIALOG:{
310 XRayMtl* m = (XRayMtl*)map->GetParamBlock()->GetOwner();
311 m->UpdateExtraParams( m->GetShader()->SupportStdParams() );
312 return TRUE;
313 }
314 }
315 return FALSE;
316 }
DeleteThis()317 void DeleteThis() { }
318 };
319
320 static ExtraDlgProc extraDlgProc;
321
322 // extended parameters
323 static ParamBlockDesc2 std2_extended_blk ( std2_extended, _T("extendedParameters"), 0, &stdmtl2CD, P_AUTO_CONSTRUCT + P_AUTO_UI, EXTENDED_PB_REF,
324 //rollout
325 IDD_DMTL_EXTRA6, IDS_DS_EXTRA, 0, APPENDROLL_CLOSED, &extraDlgProc,
326 // params
327 std2_opacity_type, _T("opacityType"), TYPE_INT, 0, IDS_JW_OPACITYTYPE,
328 p_default, 0,
329 p_range, 0, 2,
330 p_ui, TYPE_RADIO, 3, IDC_TR_SUB2, IDC_TR_SUB, IDC_TR_ADD,
331 p_accessor, &extendedPBAccessor,
332 end,
333 std2_opacity, _T("opacity"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_DS_OPACITY,
334 p_default, 0.0,
335 p_range, 0.0, 100.0, // UI us in the shader rollout
336 p_accessor, &extendedPBAccessor,
337 end,
338 std2_filter_color, _T("filterColor"), TYPE_RGBA, P_ANIMATABLE, IDS_DS_FILTER,
339 p_default, Color(0, 0, 0),
340 p_ui, TYPE_COLORSWATCH, IDC_FILTER_CS,
341 p_accessor, &extendedPBAccessor,
342 end,
343 std2_ep_filter_map, _T("filterMap"), TYPE_TEXMAP, P_SUBTEX + P_NO_AUTO_LABELS, IDS_JW_FILTERMAP,
344 p_subtexno, ID_FI,
345 p_ui, TYPE_TEXMAPBUTTON, IDC_MAPON_FI,
346 p_accessor, &extendedPBAccessor,
347 end,
348 std2_falloff_type, _T("opacityFallOffType"), TYPE_INT, 0, IDS_JW_FALLOFFTYPE,
349 p_default, 0,
350 p_range, 0, 1,
351 p_ui, TYPE_RADIO, 2, IDC_TF_IN, IDC_TF_OUT,
352 p_accessor, &extendedPBAccessor,
353 end,
354 std2_falloff_amnt, _T("opacityFallOff"), TYPE_PCNT_FRAC, P_ANIMATABLE, IDS_DS_FALLOFF,
355 p_default, 0.0,
356 p_range, 0.0, 100.0,
357 p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_TF_EDIT, IDC_TF_SPIN, 0.1,
358 p_accessor, &extendedPBAccessor,
359 end,
360 std2_ior, _T("ior"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_IOR,
361 p_default, 1.5,
362 p_range, 0.0, 10.0,
363 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_IOR_EDIT, IDC_IOR_SPIN, 0.01,
364 p_accessor, &extendedPBAccessor,
365 end,
366 std2_wire_size, _T("wireSize"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_WIRESZ,
367 p_default, 1.0,
368 p_range, 0.0, 100.0,
369 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_WIRE_EDIT, IDC_WIRE_SPIN, 1.0,
370 p_accessor, &extendedPBAccessor,
371 end,
372 std2_wire_units, _T("wireUnits"), TYPE_INT, 0, IDS_JW_WIREUNITS,
373 p_default, 0,
374 p_range, 0, 1,
375 p_ui, TYPE_RADIO, 2, IDC_PIXELS, IDC_UNITS,
376 p_accessor, &extendedPBAccessor,
377 end,
378 std2_apply_refl_dimming, _T("applyReflectionDimming"), TYPE_BOOL, 0, IDS_JW_APPLYREFDIM,
379 p_default, FALSE,
380 p_ui, TYPE_SINGLECHEKBOX, IDC_DIM_REFL,
381 p_accessor, &extendedPBAccessor,
382 end,
383 std2_dim_lvl, _T("dimLevel"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_DIMLEV,
384 p_default, 0.0,
385 p_range, 0.0, 1.0,
386 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_DIM_AMT, IDC_DIM_AMTSPIN, 0.01,
387 p_accessor, &extendedPBAccessor,
388 end,
389 std2_refl_lvl, _T("reflectionLevel"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_DIMMULT,
390 p_default, 1.0,
391 p_range, 0.1, 10.0,
392 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_DIM_MULT, IDC_DIM_MULTSPIN, 0.01,
393 p_accessor, &extendedPBAccessor,
394 end,
395 end
396 );
397
398 ///////////////////////////////////////////////////////////////////////////////////
399 // Sampling Rollout
400 //
401 class SamplingPBAccessor : public PBAccessor
402 {
403 public:
Set(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t)404 void Set(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t) // set from v
405 {
406 XRayMtl* m = (XRayMtl*)owner;
407 macroRecorder->Disable();
408 switch (id)
409 {
410 case std2_ssampler: {
411 ClassDesc* pCD = XRayMtl::GetSamplerCD(v.i);
412 if (pCD && m->GetSamplerIndx() != NO_UPDATE )
413 {
414 m->SwitchSampler(pCD);
415 // m->samplerId = v.i;
416 }
417 } break;
418 case std2_ssampler_by_name: {
419 for (int i = 0; i < XRayMtl::NumSamplers(); i++)
420 {
421 ClassDesc* pCD = XRayMtl::GetSamplerCD(i);
422 if (_tcsicmp(pCD->ClassName(), v.s) == 0)
423 {
424 m->pb_sampling->SetValue(std2_ssampler, 0, i);
425 break;
426 }
427 }
428 } break;
429 case std2_ssampler_qual:
430 m->GetPixelSampler()->SetQuality( v.f ); break;
431 case std2_ssampler_enable:
432 m->GetPixelSampler()->SetEnable( v.i );
433 m->SetFlag(NEWSTDMTL_SSAMP_ON, v.i); break;
434
435 case std2_ssampler_adapt_threshold:
436 m->GetPixelSampler()->SetAdaptiveThreshold( v.f ); break;
437 case std2_ssampler_adapt_on:{
438 m->GetPixelSampler()->SetAdaptiveOn( v.i );
439 IParamMap2* map = m->pb_sampling ? m->pb_sampling->GetMap() : NULL;
440 if ( map ) {
441 map->Enable(std2_ssampler_adapt_threshold, v.i );
442 }
443 } break;
444 case std2_ssampler_subsample_tex_on:
445 m->GetPixelSampler()->SetTextureSuperSampleOn( v.i ); break;
446 case std2_ssampler_advanced: {
447 IParamMap2* map = m->pb_sampling ? m->pb_sampling->GetMap() : NULL;
448 HWND hwnd = ( map ) ? map->GetHWnd() : NULL;
449 m->GetPixelSampler()->ExecuteParamDialog( hwnd, m );
450 } break;
451 case std2_ssampler_param0:
452 m->GetPixelSampler()->SetOptionalParam( 0, v.f ); break;
453 case std2_ssampler_param1:
454 m->GetPixelSampler()->SetOptionalParam( 1, v.f ); break;
455
456 }
457 macroRecorder->Enable();
458 }
Get(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t,Interval & valid)459 void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval& valid) // get into v
460 {
461 XRayMtl* m = (XRayMtl*)owner;
462 switch (id)
463 {
464 case std2_ssampler_by_name: {
465 ClassDesc* pCD = XRayMtl::GetSamplerCD(m->samplerId);
466 if (pCD)
467 v.s = (TCHAR*)pCD->ClassName();
468 } break;
469 }
470 }
471 };
472
473
474 static SamplingPBAccessor samplingPBAccessor;
475
476 // sampling rollout dialog proc
477
478 class SamplingDlgProc : public ParamMap2UserDlgProc
479 {
480 public:
DlgProc(TimeValue t,IParamMap2 * map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)481 BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
482 {
483 switch (msg)
484 {
485 case WM_INITDIALOG:
486 // load the sampler dropdown
487 HWND hwndSamplerCombo = GetDlgItem(hWnd, IDC_PIX_SAMPLER);
488 SendMessage(hwndSamplerCombo, CB_RESETCONTENT, 0L, 0L);
489 for (int i = 0; i < XRayMtl::NumSamplers(); i++) {
490 ClassDesc* pClassD = XRayMtl::GetSamplerCD(i);
491 int n = SendMessage(hwndSamplerCombo, CB_ADDSTRING, 0L, (LPARAM)(pClassD->ClassName()) );
492 SendMessage(hwndSamplerCombo, CB_SETITEMDATA, n, (LPARAM)pClassD );
493 }
494 XRayMtl* m = (XRayMtl*)map->GetParamBlock()->GetOwner();
495 // Class_ID sampId = m->GetPixelSampler()->ClassID();
496
497 // JohnW: Are these still necessary? removed setindx 3/23/99 ke
498 macroRecorder->Disable();
499 // m->SetSamplerIndx( m->FindSampler( sampId ) );
500 m->UpdateSamplingParams();
501 macroRecorder->Enable();
502 return TRUE;
503 }
504 return FALSE;
505 }
DeleteThis()506 void DeleteThis() { }
507 };
508
509 static SamplingDlgProc samplingDlgProc;
510
511 // supersampling parameters
512 static ParamBlockDesc2 std2_sampling_blk ( std2_sampling, _T("samplingParameters"), 0, &stdmtl2CD, P_AUTO_CONSTRUCT + P_AUTO_UI, SAMPLING_PB_REF,
513 //rollout
514 IDD_DMTL_SAMPLING3, IDS_KE_SAMPLING, 0, APPENDROLL_CLOSED, &samplingDlgProc,
515 // params
516 std2_ssampler, _T("sampler"), TYPE_INT, 0, IDS_JW_PIXELSAMPLER,
517 p_default, 0,
518 p_ui, TYPE_INTLISTBOX, IDC_PIX_SAMPLER, 0,
519 p_accessor, &samplingPBAccessor,
520 end,
521 std2_ssampler_qual, _T("samplerQuality"), TYPE_FLOAT, P_ANIMATABLE, IDS_JW_SAMPLERQUAL,
522 p_default, 0.5,
523 p_range, 0.0, 1.0,
524 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_SAMPLEQUALITY_EDIT, IDC_SAMPLEQUALITY_SPIN, 0.01,
525 p_accessor, &samplingPBAccessor,
526 end,
527 std2_ssampler_enable, _T("samplerEnable"), TYPE_BOOL, P_ANIMATABLE, IDS_JW_SAMPLERENABLE,
528 p_default, FALSE,
529 p_ui, TYPE_SINGLECHEKBOX, IDC_SUPER_SAMP,
530 p_accessor, &samplingPBAccessor,
531 end,
532 std2_ssampler_adapt_threshold, _T("samplerAdaptThreshold"), TYPE_FLOAT, 0, IDS_KE_SAMPLERADAPTTHRESH,
533 p_default, 0.1,
534 p_range, 0.0, 1.0,
535 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_THRESHOLD_EDIT, IDC_THRESHOLD_SPIN, 0.001,
536 p_accessor, &samplingPBAccessor,
537 end,
538 std2_ssampler_adapt_on, _T("samplerAdaptOn"), TYPE_BOOL, 0, IDS_KE_SAMPLERADAPTON,
539 p_default, TRUE,
540 p_ui, TYPE_SINGLECHEKBOX, IDC_ADAPT_ON,
541 p_accessor, &samplingPBAccessor,
542 end,
543 std2_ssampler_subsample_tex_on, _T("subSampleTextureOn"), TYPE_BOOL, 0, IDS_KE_SUBSAMPLE_TEX_ON,
544 p_default, TRUE,
545 p_ui, TYPE_SINGLECHEKBOX, IDC_SAMPLE_TEX,
546 p_accessor, &samplingPBAccessor,
547 end,
548 std2_ssampler_advanced, _T("samplerAdvancedOptions"), TYPE_BOOL, 0, IDS_KE_SAMPLERADVANCED,
549 p_default, TRUE,
550 p_ui, TYPE_SINGLECHEKBOX, IDC_ADVANCED_BUTTON,
551 p_accessor, &samplingPBAccessor,
552 end,
553 std2_ssampler_by_name, _T("samplerByName"), TYPE_STRING, 0, IDS_JW_SAMPLERBYNAME,
554 p_accessor, &samplingPBAccessor,
555 end,
556 std2_ssampler_param0, _T("UserParam0"), TYPE_FLOAT, 0, IDS_KE_SAMPLER_PARAM0,
557 p_default, 0.0,
558 p_range, 0.0, 1.0,
559 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_PARAM0_EDIT, IDC_PARAM0_SPIN, 0.01,
560 p_accessor, &samplingPBAccessor,
561 end,
562 std2_ssampler_param1, _T("UserParam1"), TYPE_FLOAT, 0, IDS_KE_SAMPLER_PARAM1,
563 p_default, 0.0,
564 p_range, 0.0, 1.0,
565 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_PARAM1_EDIT, IDC_PARAM1_SPIN, 0.01,
566 p_accessor, &samplingPBAccessor,
567 end,
568 end
569 );
570
571 class XRayPBAccessor : public PBAccessor
572 {
573 public:
Set(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t)574 void Set(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t) // set from v
575 {
576 XRayMtl* m = (XRayMtl*)owner;
577 switch (id)
578 {
579 case std2_eshader_type:
580 m->eshaderId = (m->GetEShader(v.i))?v.i:-1;
581 break;
582 case std2_cshader_type:
583 m->cshaderId = (m->GetCShader(v.i))?v.i:-1;
584 break;
585 case std2_gamemtl_type:
586 m->gamemtlId = (m->GetGameMtl(v.i))?v.i:-1;
587 break;
588 case std2_eshader_by_name: {
589 int idx = m->FindEShader(v.s);
590 if (idx>=0) m->pb_xray->SetValue(std2_eshader_type, 0, idx);
591 }break;
592 case std2_cshader_by_name: {
593 int idx = m->FindCShader(v.s);
594 if (idx>=0) m->pb_xray->SetValue(std2_cshader_type, 0, idx);
595 }break;
596 case std2_gamemtl_by_name: {
597 int idx = m->FindGameMtl(v.s);
598 if (idx>=0) m->pb_xray->SetValue(std2_gamemtl_type, 0, idx);
599 }break;
600 }
601 }
602
Get(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t,Interval & valid)603 void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval& valid) // get into v
604 {
605 XRayMtl* m = (XRayMtl*)owner;
606 switch (id)
607 {
608 case std2_eshader_by_name:{
609 v.s = m->GetEShader(m->eshaderId);
610 }break;
611 case std2_cshader_by_name:{
612 v.s = m->GetCShader(m->cshaderId);
613 }break;
614 case std2_gamemtl_by_name:{
615 v.s = m->GetGameMtl(m->gamemtlId);
616 }break;
617 }
618 }
619 };
620
621 static XRayPBAccessor xrayPBAccessor;
622
623 // shader rollout dialog proc
624 class XRayDlgProc : public ParamMap2UserDlgProc
625 {
626 public:
DlgProc(TimeValue t,IParamMap2 * map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)627 BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
628 {
629 switch (msg)
630 {
631 case WM_INITDIALOG:{
632 XRayMtl* m = (XRayMtl*)map->GetParamBlock()->GetOwner();
633 // load the shader dropdown
634 {
635 HWND hwndEShader = GetDlgItem(hWnd, IDC_ESHADER);
636 SendMessage(hwndEShader, CB_RESETCONTENT, 0L, 0L);
637 for (DWORD i = 0; i < XRayMtl::EShaders.size(); i++)
638 {
639 int n = SendMessage(hwndEShader, CB_ADDSTRING, 0L, (LPARAM)m->GetEShader(i));
640 SendMessage(hwndEShader, CB_SETITEMDATA, n, (LPARAM)i);
641 }
642 }
643 {
644 HWND hwndEShader = GetDlgItem(hWnd, IDC_CSHADER);
645 SendMessage(hwndEShader, CB_RESETCONTENT, 0L, 0L);
646 for (DWORD i = 0; i < XRayMtl::CShaders.size(); i++)
647 {
648 int n = SendMessage(hwndEShader, CB_ADDSTRING, 0L, (LPARAM)m->GetCShader(i));
649 SendMessage(hwndEShader, CB_SETITEMDATA, n, (LPARAM)i);
650 }
651 }
652 {
653 HWND hwndEShader = GetDlgItem(hWnd, IDC_GAMEMTL);
654 SendMessage(hwndEShader, CB_RESETCONTENT, 0L, 0L);
655 for (DWORD i = 0; i < XRayMtl::GameMtls.size(); i++)
656 {
657 int n = SendMessage(hwndEShader, CB_ADDSTRING, 0L, (LPARAM)m->GetGameMtl(i));
658 SendMessage(hwndEShader, CB_SETITEMDATA, n, (LPARAM)i);
659 }
660 }
661 }return TRUE;
662 }
663 return FALSE;
664 }
DeleteThis()665 void DeleteThis() { }
666 };
667
668
669 static XRayDlgProc xrayDlgProc;
670
671 // shader parameters
672 static ParamBlockDesc2 std2_xray_blk ( std2_xray, _T("Parameters"), 0, &stdmtl2CD, P_AUTO_CONSTRUCT + P_AUTO_UI, XRAY_PB_REF,
673 //rollout
674 IDD_DMTL_XRAY, IDS_KE_XRAY, 0, APPENDROLL_CLOSED, &xrayDlgProc,
675 // params
676 std2_eshader_type, _T("EShaderType"), TYPE_INT, 0, IDS_JW_ESHADERTYPE,
677 p_default, 0,
678 p_ui, TYPE_INTLISTBOX, IDC_ESHADER, 0,
679 p_accessor, &xrayPBAccessor,
680 end,
681 std2_cshader_type, _T("CShaderType"), TYPE_INT, 0, IDS_JW_CSHADERTYPE,
682 p_default, 0,
683 p_ui, TYPE_INTLISTBOX, IDC_CSHADER, 0,
684 p_accessor, &xrayPBAccessor,
685 end,
686 std2_gamemtl_type, _T("GameMtlType"), TYPE_INT, 0, IDS_JW_GAMEMTLTYPE,
687 p_default, 0,
688 p_ui, TYPE_INTLISTBOX, IDC_GAMEMTL, 0,
689 p_accessor, &xrayPBAccessor,
690 end,
691 std2_eshader_by_name, _T("EShaderByName"),TYPE_STRING, 0, IDS_JW_ESHADERBYNAME,
692 p_accessor, &xrayPBAccessor,
693 end,
694 std2_cshader_by_name, _T("CShaderByName"),TYPE_STRING, 0, IDS_JW_CSHADERBYNAME,
695 p_accessor, &xrayPBAccessor,
696 end,
697 std2_gamemtl_by_name, _T("GameMtlByName"),TYPE_STRING, 0, IDS_JW_GAMEMTLBYNAME,
698 p_accessor, &xrayPBAccessor,
699 end,
700 end
701 );
702
703 //////////////////////////////////////////end, sampling
704 static HIMAGELIST hLockButtons = NULL;
705
706 // mjm - begin - 5.10.99
707 class ResourceDelete
708 {
709 public:
ResourceDelete()710 ResourceDelete() {}
~ResourceDelete()711 ~ResourceDelete() { if (hLockButtons) ImageList_Destroy(hLockButtons); }
712 };
713
714 static ResourceDelete theResourceDelete;
715 // mjm - end
716
SetupPadLockButton(HWND hWnd,int id,BOOL check)717 static void SetupPadLockButton(HWND hWnd, int id, BOOL check)
718 {
719 ICustButton *iBut;
720 iBut = GetICustButton(GetDlgItem(hWnd, id));
721 iBut->SetImage(hLockButtons, 2, 2, 2, 2, 16, 15);
722 iBut->SetType(CBT_CHECK);
723 ReleaseICustButton(iBut);
724 }
725
LoadXRayMtlResources()726 static void LoadXRayMtlResources()
727 {
728 static BOOL loaded=FALSE;
729 if (loaded) return;
730 loaded = TRUE;
731 HBITMAP hBitmap, hMask;
732 hLockButtons = ImageList_Create(16, 15, TRUE, 2, 0);
733 hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_DMTL_BUTTONS));
734 hMask = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_DMTL_MASKBUTTONS));
735 ImageList_Add(hLockButtons, hBitmap, hMask);
736 DeleteObject(hBitmap);
737 DeleteObject(hMask);
738 }
739
740 class StdMapsDlgProc : public ParamMap2UserDlgProc
741 {
742 public:
DlgProc(TimeValue t,IParamMap2 * map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)743 BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
744 {
745 XRayMtl* m = (XRayMtl*)map->GetParamBlock()->GetOwner();
746 switch (msg)
747 {
748 case WM_INITDIALOG:
749 // conditionally set map amount spinner ranges and padlock button images
750 LoadXRayMtlResources();
751 int bumpChan = m->stdIDToChannel[ ID_BU ];
752 int dispChan = m->stdIDToChannel[ ID_DP ];
753 int slevChan = m->stdIDToChannel[ ID_SS ];
754
755 for (int i = 0; i < STD2_NMAX_TEXMAPS; i++)
756 {
757 if (i == bumpChan || i == dispChan || i == slevChan)
758 map->SetRange(std2_map_amnts, -999, 999, i);
759 else
760 map->SetRange(std2_map_amnts, 0, 100, i);
761 }
762
763 SetupPadLockButton(hWnd, IDC_LOCK_TEX01, TRUE);
764 macroRecorder->Disable();
765 {
766 KillRefmsg kill( m->killRefmsg );
767 m->UpdateLockADTex(TRUE);
768 }
769 macroRecorder->Enable();
770 return TRUE;
771 }
772 return FALSE;
773 }
774
DeleteThis()775 void DeleteThis() { }
776 };
777
778 static StdMapsDlgProc stdMapsDlgProc;
779
IsMultipleInstanced(XRayMtl * m,Texmap * t)780 static BOOL IsMultipleInstanced(XRayMtl *m, Texmap *t) {
781 int cnt=0;
782 for (int i = 0; i < STD2_NMAX_TEXMAPS; i++) {
783 if (m->maps->txmap[i].map == t)
784 cnt++;
785 }
786 return (cnt>1)?TRUE:FALSE;
787 }
788
789 #define BUMP_DEF_AMT .30f
790
791 class MapsPBAccessor : public PBAccessor
792 {
793 public:
794 // the texture maps are stored, as before, in the Texmaps structure, so the parameters in the
795 // pb_map block act as 'views' onto this structure. Any setting of map info (say from the scripter)
796 // is reflected here in the Texmaps structure, and any getting of map info is extracted here from
797 // this structure.
798
799 // I hope to be able to host the texmap stuff entirely in the paramblock when I get assignable subanim
800 // numbers supported in PB2's (so that the map, map enable and map amount Tab<>s are number in interleaved row order)
Set(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t)801 void Set(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t) // set from v
802 {
803 XRayMtl* m = (XRayMtl*)owner;
804 switch (id)
805 {
806 case std2_map_enables:
807 m->maps->txmap[tabIndex].mapOn = v.i;
808 m->UpdateMapButtons();
809 m->UpdateExtendedMapButtons();
810 break;
811
812 case std2_maps:
813 {
814 Texmap* tex = (Texmap*)v.r;
815 m->maps->ReplaceReference(2*tabIndex+1, tex);
816 if (tex != NULL) {
817 macroRecorder->Disable();
818 m->EnableMap(tabIndex, TRUE);
819 macroRecorder->Enable();
820 if (m->maps->txmap[tabIndex].amtCtrl == NULL) {
821 m->maps->ReplaceReference(2*tabIndex, NewDefaultFloatController());
822 m->maps->txmap[tabIndex].amtCtrl->SetValue(TimeValue(0), &m->maps->txmap[tabIndex].amount);
823 }
824 } else {
825 if (m->maps->txmap[tabIndex].amtCtrl != NULL)
826 m->maps->DeleteReference(2*tabIndex);
827 macroRecorder->Disable();
828 m->SetTexmapAmt(tabIndex, ((tabIndex == m->stdIDToChannel[ID_BU]) ? BUMP_DEF_AMT : 1.0f), TimeValue(0));
829 m->EnableMap(tabIndex, FALSE);
830 macroRecorder->Enable();
831 }
832 if (tex && (tabIndex == m->stdIDToChannel[ID_RL]|| tabIndex == m->stdIDToChannel[ID_RR]) ){
833 if (!IsMultipleInstanced(m,tex)) { //DS 4/26/99: keep settings for instanced map
834 UVGen* uvg0 = tex->GetTheUVGen();
835 if (uvg0 && uvg0->IsStdUVGen()) {
836 StdUVGen *uvg = (StdUVGen*)uvg0;
837 uvg->InitSlotType(MAPSLOT_ENVIRON);
838 uvg->SetCoordMapping(UVMAP_SPHERE_ENV);
839 }
840 }
841 }
842 m->UpdateMapButtons();
843 m->UpdateExtendedMapButtons();
844
845 break;
846 }
847
848 case std2_map_amnts:
849 {
850 // Kill the refmessage from the map, since it will
851 // be fixed later by the ref message for std2_map_amnts.
852 KillRefmsg kill(m->killRefmsg);
853 if (m->maps->txmap[tabIndex].amtCtrl)
854 m->maps->txmap[tabIndex].amtCtrl->SetValue(t, &v.f);
855 m->maps->txmap[tabIndex].amount = v.f;
856 if (tabIndex == m->stdIDToChannel[ID_BU])
857 m->mInRQ = chooseReshade[m->mInRQ][IReshading::RR_NeedPreshade];
858 }
859 break;
860
861 case std2_mp_ad_texlock:
862 m->SetFlag(NEWSTDMTL_LOCK_ADTEX, v.i);
863 m->UpdateLockADTex(TRUE);
864 // removed to avoid multiple viewport redraws on change shader
865 // m->UpdateMtlDisplay();
866 break;
867 }
868 }
869
Get(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t,Interval & valid)870 void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval& valid) // set from v
871 {
872 XRayMtl* m = (XRayMtl*)owner;
873 switch (id)
874 {
875 case std2_map_enables:
876 v.i = m->maps->txmap[tabIndex].mapOn; break;
877 case std2_maps:
878 v.r = m->maps->txmap[tabIndex].map; break;
879 case std2_map_amnts:
880 if (m->maps->txmap[tabIndex].amtCtrl)
881 m->maps->txmap[tabIndex].amtCtrl->GetValue(t, &v.f, valid);
882 else
883 v.f = m->maps->txmap[tabIndex].amount;
884 break;
885 }
886 }
887
888 // this allows 'virtual' parameters to refelect key state if in spinners and the underlying
889 // source parameter is animatable (map amount in this case)
KeyFrameAtTime(ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t)890 BOOL KeyFrameAtTime(ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t)
891 {
892 if (id == std2_map_amnts)
893 return ((XRayMtl*)owner)->AmtKeyAtTime(tabIndex, t);
894 else
895 return FALSE;
896 }
897
898 };
899 static MapsPBAccessor mapsPBAccessor;
900
901
902 // std_maps parameters
903 static ParamBlockDesc2 std_maps_blk ( std_maps, _T("maps"), 0, &stdmtl2CD, P_AUTO_CONSTRUCT + P_AUTO_UI, MAPS_PB_REF,
904 //rollout
905 IDD_DMTL_TEXMAP4, IDS_DS_TEXMAP, 0, APPENDROLL_CLOSED, &stdMapsDlgProc,
906 // params
907 std2_map_enables, _T("mapEnables"), TYPE_BOOL_TAB, STD2_NMAX_TEXMAPS, 0, IDS_JW_MAPENABLES,
908 p_default, FALSE,
909 p_ui, TYPE_SINGLECHEKBOX, IDC_USEMAP_0, IDC_USEMAP_1, IDC_USEMAP_2, IDC_USEMAP_3,
910 IDC_USEMAP_4, IDC_USEMAP_5, IDC_USEMAP_6, IDC_USEMAP_7,
911 IDC_USEMAP_8, IDC_USEMAP_9, IDC_USEMAP_10, IDC_USEMAP_11,
912 IDC_USEMAP_12, IDC_USEMAP_13, IDC_USEMAP_14, IDC_USEMAP_15,
913 IDC_USEMAP_16, IDC_USEMAP_17, IDC_USEMAP_18, IDC_USEMAP_19,
914 IDC_USEMAP_20, IDC_USEMAP_21, IDC_USEMAP_22, IDC_USEMAP_23,
915 p_accessor, &mapsPBAccessor,
916 end,
917 std2_maps, _T("maps"), TYPE_TEXMAP_TAB, STD2_NMAX_TEXMAPS, P_NO_REF, IDS_JW_MAPS,
918 p_ui, TYPE_TEXMAPBUTTON, IDC_MAP_0, IDC_MAP_1, IDC_MAP_2, IDC_MAP_3,
919 IDC_MAP_4, IDC_MAP_5, IDC_MAP_6, IDC_MAP_7,
920 IDC_MAP_8, IDC_MAP_9, IDC_MAP_10, IDC_MAP_11,
921 IDC_MAP_12, IDC_MAP_13, IDC_MAP_14, IDC_MAP_15,
922 IDC_MAP_16, IDC_MAP_17, IDC_MAP_18, IDC_MAP_19,
923 IDC_MAP_20, IDC_MAP_21, IDC_MAP_22, IDC_MAP_23,
924 p_accessor, &mapsPBAccessor,
925 end,
926 std2_map_amnts, _T("mapAmounts"), TYPE_PCNT_FRAC_TAB, STD2_NMAX_TEXMAPS, 0, IDS_JW_MAPAMOUNTS,
927 p_default, 1.0, // default is given in internal units JBW 10.8.99
928 p_range, 0.0, 100.0,
929 p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_AMTEDIT_0, IDC_AMTSPIN_0, IDC_AMTEDIT_1, IDC_AMTSPIN_1,
930 IDC_AMTEDIT_2, IDC_AMTSPIN_2, IDC_AMTEDIT_3, IDC_AMTSPIN_3,
931 IDC_AMTEDIT_4, IDC_AMTSPIN_4, IDC_AMTEDIT_5, IDC_AMTSPIN_5,
932 IDC_AMTEDIT_6, IDC_AMTSPIN_6, IDC_AMTEDIT_7, IDC_AMTSPIN_7,
933 IDC_AMTEDIT_8, IDC_AMTSPIN_8, IDC_AMTEDIT_9, IDC_AMTSPIN_9,
934 IDC_AMTEDIT_10, IDC_AMTSPIN_10, IDC_AMTEDIT_11, IDC_AMTSPIN_11,
935 IDC_AMTEDIT_12, IDC_AMTSPIN_12, IDC_AMTEDIT_13, IDC_AMTSPIN_13,
936 IDC_AMTEDIT_14, IDC_AMTSPIN_14, IDC_AMTEDIT_15, IDC_AMTSPIN_15,
937 IDC_AMTEDIT_16, IDC_AMTSPIN_16, IDC_AMTEDIT_17, IDC_AMTSPIN_17,
938 IDC_AMTEDIT_18, IDC_AMTSPIN_18, IDC_AMTEDIT_19, IDC_AMTSPIN_19,
939 IDC_AMTEDIT_20, IDC_AMTSPIN_20, IDC_AMTEDIT_21, IDC_AMTSPIN_21,
940 IDC_AMTEDIT_22, IDC_AMTSPIN_22, IDC_AMTEDIT_23, IDC_AMTSPIN_23,
941 1.0,
942 p_accessor, &mapsPBAccessor,
943 end,
944 std2_mp_ad_texlock, _T("adTextureLock"), TYPE_BOOL, 0, IDS_JW_ADTEXLOCK,
945 p_default, TRUE,
946 p_ui, TYPE_CHECKBUTTON, IDC_LOCK_TEX01,
947 p_accessor, &mapsPBAccessor,
948 end,
949 end
950 );
951
952 #ifndef DESIGN_VER
953 // std2_dynamics parameters
954 static ParamBlockDesc2 std2_dynamics_blk ( std2_dynamics, _T("dynamicsParameters"), 0, &stdmtl2CD, P_AUTO_CONSTRUCT + P_AUTO_UI, DYNAMICS_PB_REF,
955 //rollout
956 IDD_DMTL_DYNAM, IDS_DS_DYNAMICS, 0, APPENDROLL_CLOSED, NULL,
957 // params
958 std2_bounce, _T("bounce"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_BOUNCE,
959 p_default, 1.0,
960 p_range, 0.0, 1.0,
961 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_BOUNCE_EDIT, IDC_BOUNCE_SPIN, 0.01,
962 end,
963 std2_static_friction, _T("staticFriction"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_STATFRIC,
964 p_default, 0.0,
965 p_range, 0.0, 1.0,
966 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_STATFRIC_EDIT, IDC_STATFRIC_SPIN, 0.01,
967 end,
968 std2_sliding_friction, _T("slidingFriction"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_SLIDFRIC,
969 p_default, 0.0,
970 p_range, 0.0, 1.0,
971 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_SLIDFRIC_EDIT, IDC_SLIDFRIC_SPIN, 0.01,
972 end,
973 end
974 );
975 #endif
976
977 // Old Parameter block indices, kept around for old-version loading
978 #define PB_AMBIENT_O 0
979 #define PB_DIFFUSE_O 1
980 #define PB_SPECULAR_O 2
981 #define PB_SHININESS_O 3
982 #define PB_SHIN_STR_O 4
983 #define PB_SELFI_O 5
984 #define PB_OPAC_O 6
985 #define PB_OPFALL_O 7
986 #define PB_FILTER_O 8
987 #define PB_WIRESZ_O 9
988 #define PB_IOR_O 10
989 #define PB_BOUNCE_O 11
990 #define PB_STATFRIC_O 12
991 #define PB_SLIDFRIC_O 13
992 #define PB_DIMLEV_O 14
993 #define PB_DIMMULT_O 15
994 #define PB_SOFTEN_O 16
995 #define PB_SELFILLUM_CLR_O 17
996
997 // Ver. 10 Parameter block indices
998 #define PB_OPAC 0
999 #define PB_OPFALL 1
1000 #define PB_FILTER 2
1001 #define PB_WIRESZ 3
1002 #define PB_IOR 4
1003 #define PB_BOUNCE 5
1004 #define PB_STATFRIC 6
1005 #define PB_SLIDFRIC 7
1006 #define PB_DIMLEV 8
1007 #define PB_DIMMULT 9
1008
1009 #define CURRENT_NEWSTDMTL_VERSION 12
1010 #define FINAL_PARAMBLOCK_v1_VERSION 10
1011
1012 #define NPARAMS 10
1013 #define XRAYMTL_PBVERSION 1
1014 #define NEWSTDMTL_PBVERSION 9
1015
1016 // conversion descriptors for old ParamBlocks to ParamBlock2s
1017 // here we have two version descriptors, one for parameters going into
1018 // new pb_extended pblock, the other for params going into the
1019 // new pb_dynamics block. The -1 ID's below indicate no copy,
1020 // so we use to update calls to distribute old params from one block
1021 // into two new blocks
1022
1023 static ParamBlockDescID extVer10[] = {
1024 { TYPE_FLOAT, NULL, TRUE, std2_opacity }, // opacity
1025 { TYPE_FLOAT, NULL, TRUE, std2_falloff_amnt }, // opfalloff
1026 { TYPE_RGBA, NULL, TRUE, std2_filter_color }, // filter
1027 { TYPE_FLOAT, NULL, TRUE, std2_wire_size }, // wireSize
1028 { TYPE_FLOAT, NULL, TRUE, std2_ior }, // index of refraction
1029 { TYPE_FLOAT, NULL, TRUE, -1 }, // bounce
1030 { TYPE_FLOAT, NULL, TRUE, -1 }, // static friction
1031 { TYPE_FLOAT, NULL, TRUE, -1 }, // sliding friction
1032 { TYPE_FLOAT, NULL, TRUE, std2_dim_lvl }, // reflect dim level
1033 { TYPE_FLOAT, NULL, TRUE, std2_refl_lvl }, // reflect dim multiplier
1034 };
1035
1036 static ParamBlockDescID dynVer10[] = {
1037 { TYPE_FLOAT, NULL, TRUE, -1 }, // opacity
1038 { TYPE_FLOAT, NULL, TRUE, -1 }, // opfalloff
1039 { TYPE_RGBA, NULL, TRUE, -1 }, // filter
1040 { TYPE_FLOAT, NULL, TRUE, -1 }, // wireSize
1041 { TYPE_FLOAT, NULL, TRUE, -1 }, // index of refraction
1042 { TYPE_FLOAT, NULL, TRUE, std2_bounce }, // bounce
1043 { TYPE_FLOAT, NULL, TRUE, std2_static_friction }, // static friction
1044 { TYPE_FLOAT, NULL, TRUE, std2_sliding_friction }, // sliding friction
1045 { TYPE_FLOAT, NULL, TRUE, -1 }, // reflect dim level
1046 { TYPE_FLOAT, NULL, TRUE, -1 }, // reflect dim multiplier
1047 };
1048
1049 // v10 Param Block Descriptor
1050 static ParamBlockDescID stdmtl2PB[ NPARAMS ] = {
1051 { TYPE_FLOAT, NULL, TRUE, 7 }, // opacity
1052 { TYPE_FLOAT, NULL, TRUE, 8 }, // opfalloff
1053 { TYPE_RGBA, NULL, TRUE, 9 }, // filter
1054 { TYPE_FLOAT, NULL, TRUE, 10 }, // wireSize
1055 { TYPE_FLOAT, NULL, TRUE, 11 }, // index of refraction
1056 { TYPE_FLOAT, NULL, TRUE, 12 }, // bounce
1057 { TYPE_FLOAT, NULL, TRUE, 13 }, // static friction
1058 { TYPE_FLOAT, NULL, TRUE, 14 }, // sliding friction
1059 { TYPE_FLOAT, NULL, TRUE, 15 }, // reflect dim level
1060 { TYPE_FLOAT, NULL, TRUE, 16 }, // reflect dim multiplier
1061 };
1062
1063 #define NPARAMS_O 17
1064
1065 //Old (2.5 and before) Param Block Descriptor
1066 static ParamBlockDescID stdmtlPB[ NPARAMS_O ] = {
1067 { TYPE_RGBA, NULL, TRUE, 1 }, // ambient
1068 { TYPE_RGBA, NULL, TRUE, 2 }, // diffuse
1069 { TYPE_RGBA, NULL, TRUE, 3 }, // specular
1070 { TYPE_FLOAT, NULL, TRUE, 4 }, // shininess
1071 { TYPE_FLOAT, NULL, TRUE, 5 }, // shini_strength
1072 { TYPE_FLOAT, NULL, TRUE, 6 }, // self-illum
1073 { TYPE_FLOAT, NULL, TRUE, 7 }, // opacity
1074 { TYPE_FLOAT, NULL, TRUE, 8 }, // opfalloff
1075 { TYPE_RGBA, NULL, TRUE, 9 }, // filter
1076 { TYPE_FLOAT, NULL, TRUE, 10 }, // wireSize
1077 { TYPE_FLOAT, NULL, TRUE, 11 }, // index of refraction
1078 { TYPE_FLOAT, NULL, TRUE, 12 }, // bounce
1079 { TYPE_FLOAT, NULL, TRUE, 13 }, // static friction
1080 { TYPE_FLOAT, NULL, TRUE, 14 }, // sliding friction
1081 { TYPE_FLOAT, NULL, TRUE, 15 }, // reflect dim level
1082 { TYPE_FLOAT, NULL, TRUE, 16 }, // reflect dim multiplier
1083 { TYPE_FLOAT, NULL, TRUE, 17 } // soften
1084 };
1085
1086 // Descriptor for mapping old (2.5 and before) shader parameters into new stdShader PB2's
1087 // Shader::ConvertParamBlock() uses this to extract old mtl shader params into new Shader
1088 static ParamBlockDescID stdmtlPB2[ NPARAMS_O ] = {
1089 { TYPE_RGBA, NULL, TRUE, shdr_ambient }, // ambient
1090 { TYPE_RGBA, NULL, TRUE, shdr_diffuse }, // diffuse
1091 { TYPE_RGBA, NULL, TRUE, shdr_specular }, // specular
1092 { TYPE_FLOAT, NULL, TRUE, shdr_glossiness }, // shininess
1093 { TYPE_FLOAT, NULL, TRUE, shdr_spec_lvl }, // shini_strength
1094 { TYPE_FLOAT, NULL, TRUE, shdr_self_illum_amnt }, // self-illum
1095 { TYPE_FLOAT, NULL, TRUE, -1 }, // opacity
1096 { TYPE_FLOAT, NULL, TRUE, -1 }, // opfalloff
1097 { TYPE_RGBA, NULL, TRUE, -1 }, // filter
1098 { TYPE_FLOAT, NULL, TRUE, -1 }, // wireSize
1099 { TYPE_FLOAT, NULL, TRUE, -1 }, // index of refraction
1100 { TYPE_FLOAT, NULL, TRUE, -1 }, // bounce
1101 { TYPE_FLOAT, NULL, TRUE, -1 }, // static friction
1102 { TYPE_FLOAT, NULL, TRUE, -1 }, // sliding friction
1103 { TYPE_FLOAT, NULL, TRUE, -1 }, // reflect dim level
1104 { TYPE_FLOAT, NULL, TRUE, -1 }, // reflect dim multiplier
1105 { TYPE_FLOAT, NULL, TRUE, shdr_soften } // soften
1106 };
1107 #define NUMOLDVER 1
1108 static ParamVersionDesc oldXRayMtlVersions[ NUMOLDVER ] = {
1109 ParamVersionDesc(stdmtl2PB, NPARAMS, 0),
1110 };
1111
1112 #define NEWSTDMTL_NUMOLDVER 9
1113
1114 static ParamVersionDesc oldNewStdMtlVersions[ NEWSTDMTL_NUMOLDVER+1 ] = {
1115 ParamVersionDesc(stdmtlPB, 8, 0),
1116 ParamVersionDesc(stdmtlPB, 9, 1),
1117 ParamVersionDesc(stdmtlPB, 9, 2),
1118 ParamVersionDesc(stdmtlPB, 10, 3),
1119 ParamVersionDesc(stdmtlPB, 11, 4),
1120 ParamVersionDesc(stdmtlPB, 14, 5),
1121 ParamVersionDesc(stdmtlPB, 15, 6),
1122 ParamVersionDesc(stdmtlPB, 15, 7),
1123 ParamVersionDesc(stdmtlPB, 16, 8),
1124 ParamVersionDesc(stdmtlPB, 17, 9)
1125 };
1126
1127 static ParamVersionDesc curVersion(stdmtl2PB, NPARAMS, XRAYMTL_PBVERSION);
1128 static ParamVersionDesc stdMtlVersion(stdmtlPB, NPARAMS_O, NEWSTDMTL_PBVERSION);
1129
1130 #define IDT_MYTIMER 1010
1131 #define DRAGTHRESH 6
1132 #define DITHER_WHEN_INACTIVE // avoids palette conflict probs
1133
1134 //-----------------------------------------------------------------------------
1135 // XRayMtl
1136 //-----------------------------------------------------------------------------
1137 /*
1138 TCHAR* XRayMtl::get_string(int i)
1139 {
1140 return strings[i];
1141 }
1142
1143 int XRayMtl::n_strings()
1144 {
1145 return strings.Count();
1146 }
1147 */
GetInterface(ULONG id)1148 void* XRayMtl::GetInterface(ULONG id)
1149 {
1150 if( id == IID_IReshading )
1151 return (IReshading*)( this );
1152 // else if ( id == IID_IValidityToken )
1153 // return (IValidityToken*)( this );
1154 else
1155 return Mtl::GetInterface(id);
1156 }
1157
1158
Reset()1159 void XRayMtl::Reset()
1160 {
1161 ReplaceReference( TEXMAPS_REF, new Texmaps((MtlBase*)this));
1162 ivalid.SetEmpty();
1163
1164 SetShaderIndx( FindShader( Class_ID(DEFAULT_SHADER_CLASS_ID,0) ));
1165 // back in 4.28, as it broke reset....fixed in shader.reset so only allocs pb if not there
1166 pShader->Reset(); // mjm - 4.22.99 - fix mem leak (pblock already created through SetShaderIndx() above.
1167
1168 SetSamplerIndx( FindSampler( Class_ID(DEFAULT_SAMPLER_CLASS_ID,0) ) );
1169
1170 // HEY!! this should all be done automatically in ParamBlock init...
1171 macroRecorder->Disable(); // don't want to see this parameter reset in macrorecorder
1172 // ensure all map-related parameters are set up
1173 UpdateMapButtons(); // calls updatetexmaps
1174 UpdateExtendedMapButtons();
1175
1176 pb_shader->SetValue(std2_wire, 0, FALSE );
1177 pb_shader->SetValue(std2_two_sided, 0, FALSE );
1178 pb_shader->SetValue(std2_faceted, 0, FALSE );
1179 pb_shader->SetValue(std2_face_map, 0, FALSE );
1180
1181 SetDimIntens( 0.0f, 0 );
1182 SetDimMult( 3.0f, 0 );
1183
1184 pb_extended->SetValue(std2_opacity_type, 0, 0 );
1185 pb_extended->SetValue(std2_falloff_type, 0, 0 );
1186 pb_extended->SetValue(std2_wire_units, 0, 0 );
1187 pb_extended->SetValue(std2_apply_refl_dimming, 0, FALSE );
1188 SetOpacity(1.0f, 0);
1189 SetFilter(Color(.5f, .5f, .5f), 0);
1190 SetIOR(1.5f, 0);
1191
1192 // sampling
1193 SetSamplingQuality( 0.5f );
1194 SetSamplingOn( FALSE );
1195 pb_sampling->SetValue(std2_ssampler_subsample_tex_on, 0, TRUE );
1196 pb_sampling->SetValue(std2_ssampler_adapt_threshold, 0, .1f );
1197 pb_sampling->SetValue(std2_ssampler_adapt_on, 0, TRUE );
1198
1199 SetOpacFalloff(0.0f, 0);
1200 SetWireSize(1.0f, 0);
1201 int bumpChan = stdIDToChannel[ ID_BU ];
1202 SetTexmapAmt(bumpChan, BUMP_DEF_AMT, 0);
1203 SetDynamicsProperty(0, 0, DYN_BOUNCE, 1.0f);
1204 SetDynamicsProperty(0, 0, DYN_STATIC_FRICTION, 0.0f);
1205 SetDynamicsProperty(0, 0, DYN_SLIDING_FRICTION, 0.0f);
1206
1207 SetEShaderIndx(FindEShader("default"));
1208 SetCShaderIndx(FindCShader("default"));
1209 SetGameMtlIndx(FindGameMtl("default"));
1210
1211 macroRecorder->Enable();
1212 }
1213
XRayMtl(BOOL loading)1214 XRayMtl::XRayMtl(BOOL loading) : mReshadeRQ(RR_None), mInRQ(RR_None) // mjm - 06.02.00
1215 {
1216 texHandle[0] = texHandle[1] = NULL;
1217 texHandleValid.SetEmpty();
1218
1219 pixelSampler = NULL;
1220 samplerId = -1;
1221
1222 filterOverrideOn = FALSE;
1223 filterSz = 1.0f;
1224 ioRefract = 1.5f;
1225
1226 old_pblock = NULL;
1227 pb_xray = pb_shader = pb_extended = pb_sampling = pb_maps = pb_dynamics = NULL;
1228 maps = NULL;
1229 filter = Color(0.0f, 0.0f, 0.0f);
1230 pShader = NULL;
1231 shaderId = -1;
1232 flags = NEWSTDMTL_FILT_TRANSP | NEWSTDMTL_ROLLUP1_OPEN;
1233
1234 dimReflect = FALSE;
1235 dimIntens = 0.0f;
1236 dimMult = 2.0f;
1237 wireSize = opacity = 1.0f;
1238 opfall = 0.0f;
1239 for ( int i = 0; i < 12; ++i )
1240 stdIDToChannel[i] = -1;
1241
1242 for ( i = 0; i < STD2_NMAX_TEXMAPS; ++i )
1243 channelTypes[i] = UNSUPPORTED_CHANNEL;
1244
1245 ivalid.SetEmpty();
1246
1247 /*
1248 if(strings.Count() == 0)
1249 {
1250 char path[MAX_PATH];
1251 sprintf(path, "%s/%s", GetCOREInterface()->GetDir(APP_PLUGCFG_DIR), "strings.txt");
1252 FILE* fstr = fopen(path, "r");
1253 if(fstr != NULL)
1254 {
1255 while(!feof(fstr))
1256 {
1257 TCHAR str[100];
1258
1259 _fgetts(str, 100, fstr);
1260 TCHAR* res_str = _tcsdup(str);
1261 strings.Append(1, &res_str);
1262 }
1263 fclose(fstr);
1264 }
1265 }
1266 */
1267 if (!loading){
1268 // ask the ClassDesc to make the P_AUTO_CONSTRUCT paramblocks
1269 stdmtl2CD.MakeAutoParamBlocks(this);
1270 Reset();
1271 }
1272 }
1273
Clone(RemapDir & remap)1274 RefTargetHandle XRayMtl::Clone(RemapDir &remap) {
1275 //DebugPrint(" Cloning NEWSTDMTL %d \n", ++numNewStdMtls);
1276 macroRecorder->Disable();
1277 XRayMtl *mnew = new XRayMtl(TRUE);
1278 *((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
1279 mnew->ReplaceReference(TEXMAPS_REF, remap.CloneRef(maps));
1280 mnew->ReplaceReference(SHADER_REF, remap.CloneRef(pShader));
1281 mnew->ReplaceReference(XRAY_PB_REF, remap.CloneRef(pb_xray));
1282 mnew->ReplaceReference(SHADER_PB_REF, remap.CloneRef(pb_shader));
1283 mnew->ReplaceReference(EXTENDED_PB_REF, remap.CloneRef(pb_extended));
1284 mnew->ReplaceReference(SAMPLING_PB_REF, remap.CloneRef(pb_sampling));
1285 mnew->ReplaceReference(MAPS_PB_REF, remap.CloneRef(pb_maps));
1286 #ifndef DESIGN_VER
1287 mnew->ReplaceReference(DYNAMICS_PB_REF, remap.CloneRef(pb_dynamics));
1288 #endif
1289 mnew->ReplaceReference(SAMPLER_REF, remap.CloneRef(pixelSampler));
1290
1291 mnew->ivalid.SetEmpty();
1292 mnew->flags = flags;
1293
1294 mnew->filterOverrideOn = filterOverrideOn;
1295 mnew->filterSz = filterSz;
1296
1297 mnew->ioRefract = ioRefract;
1298 mnew->opacity = opacity;
1299 mnew->filter = filter;
1300 mnew->opfall = opfall;
1301
1302 mnew->wireSize = wireSize;
1303 mnew->dimReflect = dimReflect;
1304
1305 mnew->samplerId = samplerId;
1306 mnew->shaderId = shaderId;
1307
1308 mnew->eshaderId = eshaderId;
1309 mnew->cshaderId = cshaderId;
1310 mnew->gamemtlId = gamemtlId;
1311
1312 for ( int i = 0; i < 12; ++i )
1313 mnew->stdIDToChannel[i] = stdIDToChannel[i];
1314
1315 for ( i = 0; i < STD2_NMAX_TEXMAPS; ++i )
1316 mnew->channelTypes[i] = channelTypes[i];
1317 macroRecorder->Enable();
1318 BaseClone(this, mnew, remap);
1319 return (RefTargetHandle)mnew;
1320 }
1321
CreateParamDlg(HWND hwMtlEdit,IMtlParams * imp)1322 ParamDlg* XRayMtl::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp)
1323 {
1324 KillRefmsg kill( killRefmsg );
1325
1326 Interval v;
1327 macroRecorder->Disable();
1328 Update(imp->GetTime(), v);
1329 // save the creation context for possible later shader switching requiring a new CreateParamDialog
1330 curHwmEdit = hwMtlEdit;
1331 curImp = imp;
1332 // create the rollouts, first the main shader dialog as master
1333 // note, we can't use PB2 AUTO_UI here, since the shader's dialog is to be installed in the
1334 // middle of the rollouts
1335 masterDlg = stdmtl2CD.CreateParamDlg(std2_shader, hwMtlEdit, imp, this);
1336 // then have the selected shader make its own
1337 pShaderDlg = pShader->CreateParamDialog(NULL, hwMtlEdit, imp, this,
1338 ((flags & NEWSTDMTL_ROLLUP1_OPEN) ? 0 : APPENDROLL_CLOSED));
1339 masterDlg->AddDlg(pShaderDlg);
1340 // now make the rest (they are added to the master automatically)
1341
1342 if( pShader->SupportStdParams() & STD_EXTRA_DLG )
1343 extendedDlg = stdmtl2CD.CreateParamDlg(std2_extended, hwMtlEdit, imp, this);
1344 else
1345 extendedDlg = NULL;
1346
1347 samplingDlg = stdmtl2CD.CreateParamDlg(std2_sampling, hwMtlEdit, imp, this);
1348 texmapDlg = stdmtl2CD.CreateParamDlg(std_maps, hwMtlEdit, imp, this);
1349 xrayDlg = stdmtl2CD.CreateParamDlg(std2_xray, hwMtlEdit, imp, this);
1350 UpdateTexmaps();
1351 if( pb_dynamics ) // not in the VIZ version
1352 stdmtl2CD.CreateParamDlg(std2_dynamics, hwMtlEdit, imp, this);
1353 // restore any saved rollout state
1354 stdmtl2CD.RestoreRolloutState();
1355 UpdateMapButtons();
1356 UpdateExtendedMapButtons();
1357
1358 macroRecorder->Enable();
1359 return masterDlg;
1360 }
1361
SetDlgThing(ParamDlg * dlg)1362 BOOL XRayMtl::SetDlgThing(ParamDlg* dlg)
1363 {
1364 KillRefmsg kill( killRefmsg );
1365
1366 // set the appropriate 'thing' sub-object for each secondary dialog
1367 if (dlg == pShaderDlg)
1368 {
1369 // handle material switching in the shader dialog, incoming material is 'this'
1370 assert (SuperClassID() == MATERIAL_CLASS_ID);
1371 assert (ClassID() == XRAYMTL_CLASS_ID);
1372 XRayMtl* oldMtl = (XRayMtl*)pShaderDlg->GetThing();
1373 ULONG oldParams, newParams;
1374 Class_ID newClassId, oldClassId;
1375
1376 if (oldMtl) {
1377 Shader* oldShader = oldMtl->GetShader();
1378 oldParams = oldShader->SupportStdParams();
1379 oldClassId = oldShader->ClassID();
1380 } else oldParams = 0;;
1381
1382 newParams = pShader->SupportStdParams();
1383 newClassId = pShader->ClassID();
1384
1385 if ( shaderId < 0 ) {
1386 //it's the standin shader
1387 int i = -1;
1388 // DbgAssert(0);
1389 // SetShaderIndx( FindShader( pShader->ClassID() ), FALSE );
1390 }
1391
1392 // see if we need to change Shader basic params rollup
1393 if ( (oldClassId == newClassId) ||
1394 ((newParams & STD_BASIC2_DLG) && (oldParams & STD_BASIC2_DLG)) ){
1395 assert( pShaderDlg );
1396 // update in case of partial stdParam support
1397 pShaderDlg->SetThings(this, pShader);
1398 pShader->SetParamDlg( pShaderDlg );
1399 pShaderDlg->ReloadDialog();
1400 UpdateMapButtons();
1401 } else {
1402 // different shader in this Std2Mtl, toss out the old rollup
1403 HWND oldPanel = pShaderDlg->GetHWnd();
1404 masterDlg->DeleteDlg(pShaderDlg);
1405 pShaderDlg->DeleteThis();
1406
1407 // make a new one
1408 pShaderDlg = pShader->CreateParamDialog(oldPanel, curHwmEdit, curImp, this,
1409 (flags & NEWSTDMTL_ROLLUP1_OPEN ? 0 : APPENDROLL_CLOSED));
1410 pShader->SetParamDlg(pShaderDlg);
1411 pShaderDlg->LoadDialog(TRUE);
1412 masterDlg->AddDlg(pShaderDlg);
1413
1414 UpdateMapButtons(); // calls update texmaps
1415 }
1416 }
1417 else if (dlg == texmapDlg)
1418 {
1419 texmapDlg->SetThing(this);
1420 UpdateTexmaps();
1421 UpdateLockADTex(TRUE);
1422 }
1423 else if (dlg == extendedDlg)
1424 {
1425 extendedDlg->SetThing(this);
1426 UpdateExtraParams( pShader->SupportStdParams() );
1427 UpdateExtendedMapButtons();
1428 std2_extended_blk.SetSubTexNo(std2_ep_filter_map, stdIDToChannel[ID_FI]);
1429 }
1430 else if (dlg == samplingDlg)
1431 {
1432 samplingDlg->SetThing(this);
1433 if ( samplerId < 0 ) {
1434 DbgAssert(0);
1435 // SetSamplerIndx( FindSampler( pixelSampler->ClassID() ) );
1436 }
1437 UpdateSamplingParams();
1438 }
1439 else if ( pb_dynamics == NULL )
1440 {
1441 //maybe do something here for viz case of no pb_dynamics
1442 int i = 9;
1443 }else if ( pb_xray == NULL )
1444 {
1445 //maybe do something here for viz case of no pb_dynamics
1446 int i = 9;
1447 }
1448 else
1449 return FALSE;
1450 return TRUE;
1451 }
1452
1453 // compare function for sorting Shader Tab<>
classDescListCompare(const void * elem1,const void * elem2)1454 static int __cdecl classDescListCompare(const void *elem1, const void *elem2)
1455 {
1456 ClassDesc* s1 = *(ClassDesc**)elem1;
1457 ClassDesc* s2 = *(ClassDesc**)elem2;
1458 TSTR sn1 = s1->ClassName(); // need to snap name string, since both use GetString()
1459 TSTR sn2 = s2->ClassName();
1460 return _tcscmp(sn1.data(), sn2.data());
1461 }
1462
LoadShaderList()1463 void XRayMtl::LoadShaderList()
1464 {
1465 // loads static shader list with name-sorted Shader ClassDesc*'s
1466 shaderList.ZeroCount();
1467 SubClassList* scList = GetCOREInterface()->GetDllDir().ClassDir().GetClassList(SHADER_CLASS_ID);
1468 for (long i = 0, j = 0; i < scList->Count(ACC_ALL); ++i) {
1469 if ( (*scList)[ i ].IsPublic() ) {
1470 ClassDesc* pClassD = (*scList)[ i ].CD();
1471 shaderList.Append(1, &pClassD);
1472 }
1473 }
1474 shaderList.Sort(&classDescListCompare);
1475 }
1476
NumShaders()1477 int XRayMtl::NumShaders()
1478 {
1479 if (shaderList.Count() == 0)
1480 LoadShaderList();
1481 return shaderList.Count();
1482 }
1483
GetShaderCD(int i)1484 ClassDesc* XRayMtl::GetShaderCD(int i)
1485 {
1486 if (shaderList.Count() == 0)
1487 LoadShaderList();
1488 return (i >= 0 && i < shaderList.Count()) ? shaderList[i] : NULL;
1489 }
1490
LoadSamplerList()1491 void XRayMtl::LoadSamplerList()
1492 {
1493 // loads static sampler list with name-sorted Sampler ClassDesc*'s
1494 samplerList.ZeroCount();
1495 SubClassList* scList = GetCOREInterface()->GetDllDir().ClassDir().GetClassList(SAMPLER_CLASS_ID);
1496 for (long i = 0, j = 0; i < scList->Count(ACC_ALL); ++i) {
1497 if ( (*scList)[ i ].IsPublic() ) {
1498 ClassDesc* pClassD = (*scList)[ i ].CD();
1499 samplerList.Append(1, &pClassD);
1500 }
1501 }
1502 samplerList.Sort(&classDescListCompare);
1503 }
1504
NumSamplers()1505 int XRayMtl::NumSamplers()
1506 {
1507 if (samplerList.Count() == 0)
1508 LoadSamplerList();
1509 return samplerList.Count();
1510 }
1511
GetSamplerCD(int i)1512 ClassDesc* XRayMtl::GetSamplerCD(int i)
1513 {
1514 if (samplerList.Count() == 0)
1515 LoadSamplerList();
1516 return (i >= 0 && i < samplerList.Count()) ? samplerList[i] : NULL;
1517 }
1518
1519
1520 //-------------------------------------------------------------------
1521 // DS: This class is handy for implementing UNDO - 10/31/00
1522 #if MAX_VERSION_MAJOR<=5
1523 #define SRM_CLASS_ID 0xB8073421
1524 class SingleRefMaker: public ReferenceMaker {
1525 public:
1526 RefTargetHandle rtarget;
SingleRefMaker()1527 SingleRefMaker() { rtarget = NULL; }
~SingleRefMaker()1528 ~SingleRefMaker() {
1529 DeleteAllRefsFromMe();
1530 }
SetRef(RefTargetHandle rt)1531 void SetRef(RefTargetHandle rt) {
1532 theHold.Suspend();
1533 ReplaceReference(0,rt);
1534 theHold.Resume();
1535 }
GetRef()1536 RefTargetHandle GetRef() { return rtarget; }
1537 // ReferenceMaker
NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget,PartID & partID,RefMessage message)1538 RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
1539 PartID& partID, RefMessage message ) {
1540 if (message==REFMSG_TARGET_DELETED) {
1541 if (hTarget==rtarget)
1542 rtarget = NULL;
1543 }
1544 return REF_SUCCEED;
1545 }
DeleteThis()1546 void DeleteThis() { delete this; }
1547
SuperClassID()1548 SClass_ID SuperClassID() { return SRM_CLASS_ID; }
1549 // From ref
NumRefs()1550 int NumRefs() { return 1; }
GetReference(int i)1551 RefTargetHandle GetReference(int i) { return rtarget; }
SetReference(int i,RefTargetHandle rtarg)1552 void SetReference(int i, RefTargetHandle rtarg) { rtarget = rtarg; }
CanTransferReference(int i)1553 BOOL CanTransferReference(int i) {return FALSE;}
1554 };
1555 #endif
1556
1557 //-------------------------------------------------------------------
1558 // This handles Undo/Redo of SwitchShader
1559
1560 class SwitchShaderRestore: public RestoreObj {
1561 public:
1562 XRayMtl *mtl;
1563 SingleRefMaker oldShader;
1564 SingleRefMaker newShader;
SwitchShaderRestore()1565 SwitchShaderRestore() { mtl = NULL; }
SwitchShaderRestore(XRayMtl * m,Shader * olds,Shader * news)1566 SwitchShaderRestore( XRayMtl * m, Shader *olds, Shader *news) {
1567 mtl = m;
1568 oldShader.SetRef(olds);
1569 newShader.SetRef(news);
1570 }
Restore(int isUndo)1571 void Restore(int isUndo) {
1572 mtl->SwitchShader((Shader *)oldShader.GetRef());
1573 }
Redo()1574 void Redo() {
1575 mtl->SwitchShader((Shader *)newShader.GetRef());
1576 }
Description()1577 TSTR Description() { return(TSTR(_T("SwitchShaderRestore"))); }
1578 };
1579
1580
1581 //--------------------------------------------------------------------------
1582
1583
SwitchShader(Shader * newShader,BOOL loadDlg)1584 void XRayMtl::SwitchShader(Shader* newShader, BOOL loadDlg )
1585 {
1586 // switch to a different shader
1587 SuspendAnimate();
1588 Class_ID oldShaderId = pShader? pShader->ClassID(): Class_ID(0,0);
1589 Class_ID newShaderId = newShader->ClassID();
1590 Class_ID constShaderId( CONSTClassID, 0 );
1591 if ( newShaderId != oldShaderId )
1592 {
1593 if ( pb_extended ) {
1594 int n = pb_extended->IDtoIndex( std2_opacity );
1595 pb_extended->RemoveController( n, 0);
1596 }
1597
1598 theHold.Suspend(); //-----------------------------------------------------
1599
1600 if (newShaderId == constShaderId ) { // constant
1601 SetFlag( NEWSTDMTL_FACETED, TRUE );
1602 pb_shader->SetValue(std2_faceted, 0, TRUE );
1603 } else if ( oldShaderId == constShaderId ) {
1604 SetFlag( NEWSTDMTL_FACETED, FALSE );
1605 pb_shader->SetValue(std2_faceted, 0, FALSE );
1606 }
1607
1608 Shader * oldShader = GetShader();
1609 ULONG oldParams = oldShader ? oldShader->SupportStdParams() : 0;
1610 ShaderParamDlg* oldShaderDlg = oldShader ? oldShader->GetParamDlg() : loadDlg? pShaderDlg:NULL;
1611
1612 ULONG newParams = newShader->SupportStdParams();
1613
1614 // copy any params in common
1615 if ( oldShader && newShader ){
1616 ShuffleShaderParams( newShader, oldShader );
1617 ShuffleTexMaps( newShader, oldShader );
1618 }
1619
1620 theHold.Resume(); //-----------------------------------------------------
1621
1622 if (theHold.Holding())
1623 theHold.Put(new SwitchShaderRestore(this,oldShader,newShader)); // this will make a ref to oldShader
1624
1625 theHold.Suspend(); //-----------------------------------------------------
1626
1627 // moved from below, or it crashes on reset
1628 if( oldShader) oldShader->SetParamDlg(NULL); // DS 3/9/99 ( undo may bring oldShader back, have to clear invalid pointer)
1629 if( oldShaderDlg ) oldShaderDlg->SetThings( this, NULL );
1630
1631 // NB: this deletes the oldShader ( unless it being ref'd by SwitchShaderRestore)
1632 SetShader( newShader );
1633
1634
1635 UpdateTexmaps();
1636 std2_extended_blk.SetSubTexNo(std2_ep_filter_map, stdIDToChannel[ID_FI]);
1637
1638 // update UI if open
1639 if (oldShaderDlg != NULL )
1640 {
1641 // enable or disable extra params
1642 UpdateExtraParams( newParams );
1643
1644 // now update or replace the basic rollup
1645 if ((newParams & STD_BASIC2_DLG) && (oldParams & STD_BASIC2_DLG)) {
1646 // update in case of partial stdParam support
1647 oldShaderDlg->SetThings( this, newShader );
1648 newShader->SetParamDlg( oldShaderDlg );
1649 oldShaderDlg->LoadDialog(TRUE);
1650 pShaderDlg = oldShaderDlg;
1651
1652 } else {
1653
1654 HWND oldPanel = oldShaderDlg->GetHWnd();
1655 masterDlg->DeleteDlg(oldShaderDlg);
1656 oldShaderDlg->DeleteThis();
1657
1658 // including oldPanel replaces it...
1659 pShaderDlg = newShader->CreateParamDialog(oldPanel,
1660 curHwmEdit, curImp, this,
1661 ((flags & NEWSTDMTL_ROLLUP1_OPEN) ? 0 : APPENDROLL_CLOSED));
1662 newShader->SetParamDlg(pShaderDlg,0);
1663 pShaderDlg->LoadDialog(TRUE);
1664 masterDlg->AddDlg(pShaderDlg);
1665
1666 }
1667 newShader->SetParamDlg(pShaderDlg,0);
1668 SyncADTexLock( newShader->GetLockADTex() );
1669 UpdateMapButtons();
1670 UpdateExtendedMapButtons();
1671
1672 UpdateMtlDisplay();
1673
1674 }// end, oldShaderDlg not NULL
1675
1676 theHold.Resume(); //--------------------------------------------------
1677
1678 }
1679 ResumeAnimate();
1680 }
1681
1682 // this is exposed at stdmat2 level
SwitchShader(Class_ID shaderId)1683 BOOL XRayMtl::SwitchShader(Class_ID shaderId)
1684 {
1685 ClassDesc* pCD;
1686 int n = FindShader( shaderId, &pCD );
1687 if ( pCD ){
1688 //SS 1/26/2000: fix suggested by Kells
1689 //SwitchShader(pCD);
1690 SetShaderIndx(n); // sets pb2 & set calls switchshader w/ a real shader
1691 return TRUE;
1692 }
1693 return FALSE;
1694 }
1695
1696
SwitchShader(ClassDesc * pNewCD)1697 void XRayMtl::SwitchShader(ClassDesc* pNewCD)
1698 {
1699 // create the new shader object
1700 Shader * newShader = (Shader*)(pNewCD->Create(0));
1701 newShader->Reset(); // creates pblock
1702
1703 SwitchShader( newShader );
1704 }
1705
1706
1707 // these provide R 2.5 id access to the old shaders.
SetShading(int s)1708 void XRayMtl::SetShading(int s)
1709 {
1710 long cid;
1711 pb_shader->SetValue(std2_faceted,0,FALSE);
1712 switch( s ) {
1713 case 0: cid = PHONGClassID;
1714 pb_shader->SetValue(std2_faceted,0,TRUE);
1715 break;
1716 case 1: cid = PHONGClassID; break;
1717 case 2: cid = METALClassID; break;
1718 case 3: cid = BLINNClassID; break;
1719 }
1720 long indx = FindShader( Class_ID(cid, 0) );
1721
1722 // this sets the new shader via pb2 accessor
1723 SetShaderIndx( indx );
1724 }
1725
1726 // all faceted shaders approximated by constant, all new shaders by blinn.
GetShading()1727 int XRayMtl::GetShading() {
1728 if (IsFaceted()) return 0;
1729 Class_ID id = pShader->ClassID();
1730 if ( id == Class_ID(PHONGClassID,0) ) return 1;
1731 else if ( id == Class_ID(METALClassID,0) ) return 2;
1732 return 3;
1733 }
1734
1735
1736 //-------------------------------------------------------------------
1737 // This handles Undo/Redo of SwitchSampler
1738
1739 class SwitchSamplerRestore: public RestoreObj, public ReferenceMaker {
1740 public:
1741 XRayMtl *mtl;
1742 Sampler *saveSampler;
SwitchSamplerRestore()1743 SwitchSamplerRestore() { saveSampler = NULL; mtl = NULL; }
SwitchSamplerRestore(XRayMtl * m,Sampler * s)1744 SwitchSamplerRestore( XRayMtl * m, Sampler *s) {
1745 mtl = m;
1746 saveSampler = NULL;
1747 theHold.Suspend();
1748 ReplaceReference(0,s);
1749 theHold.Resume();
1750 }
~SwitchSamplerRestore()1751 ~SwitchSamplerRestore() { DeleteAllRefsFromMe(); }
Switch()1752 void Switch() {
1753 Sampler *samp = mtl->pixelSampler;
1754
1755 samp->SetAFlag(A_LOCK_TARGET); // keeps sh from getting auto-deleted
1756 mtl->SwitchSampler(saveSampler);
1757 samp->ClearAFlag(A_LOCK_TARGET);
1758
1759 ReplaceReference(0,samp);
1760 }
Restore(int isUndo)1761 void Restore(int isUndo) { Switch(); }
Redo()1762 void Redo() { Switch(); }
Description()1763 TSTR Description() { return(TSTR(_T("SwitchSamplerRestore"))); }
1764
1765 // ReferenceMaker
NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget,PartID & partID,RefMessage message)1766 RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget,
1767 PartID& partID, RefMessage message ) {
1768 if (message==REFMSG_TARGET_DELETED) {
1769 if (hTarget==saveSampler)
1770 saveSampler = NULL;
1771 }
1772 return REF_SUCCEED;
1773 }
DeleteThis()1774 void DeleteThis() { SwitchSamplerRestore* ptr=this; delete ptr; }
1775
1776 // From ref
NumRefs()1777 int NumRefs() { return 1; }
GetReference(int i)1778 RefTargetHandle GetReference(int i) { return saveSampler; }
SetReference(int i,RefTargetHandle rtarg)1779 void SetReference(int i, RefTargetHandle rtarg) { saveSampler = (Sampler*)rtarg; }
CanTransferReference(int i)1780 BOOL CanTransferReference(int i) {return FALSE;}
1781 };
1782
1783
1784 //--------------------------------------------------------------------------
1785
1786 // copy of classid of the default sampler
1787 static Class_ID defaultSamplerID( DEFAULT_SAMPLER_CLASS_ID , 0);
1788
1789
1790
SwitchSampler(Sampler * newSampler)1791 void XRayMtl::SwitchSampler( Sampler* newSampler )
1792 {
1793 theHold.Suspend(); //-----------------------------------------------------
1794
1795 DbgAssert( newSampler );
1796 Class_ID oldSamplerId = pixelSampler? pixelSampler->ClassID(): Class_ID(0,0);
1797 Class_ID newSamplerId = newSampler->ClassID();
1798
1799 if ( oldSamplerId != newSamplerId ) {
1800
1801 theHold.Resume(); //-----------------------------------------------------
1802 if (theHold.Holding())
1803 theHold.Put(new SwitchSamplerRestore(this, pixelSampler)); // this will make a ref to oldShader
1804 theHold.Suspend(); //-----------------------------------------------------
1805
1806 SetPixelSampler( newSampler );
1807 }
1808
1809 if ( pb_sampling )
1810 UpdateSamplingParams();
1811
1812 theHold.Resume(); //-----------------------------------------------------
1813 }
1814
1815
SwitchSampler(ClassDesc * pNewCD)1816 void XRayMtl::SwitchSampler(ClassDesc* pNewCD)
1817 {
1818 // if ( ! pNewCD ) {
1819 // get default
1820 // ClassDesc* pCD;
1821 // int indx = FindSampler( defaultSamplerID, &pCD );
1822 // pNewCD = pCD;
1823 // DbgAssert( pNewCD);
1824 // }
1825 DbgAssert( pNewCD);
1826 Sampler * newSampler = (Sampler*)(pNewCD->Create(0));
1827 SwitchSampler( newSampler );
1828 }
1829
1830 // this is exposed at stdmat2 level
SwitchSampler(Class_ID samplerId)1831 BOOL XRayMtl::SwitchSampler(Class_ID samplerId){
1832 // ClassDesc* pCD;
1833 // int n = FindSampler( samplerId, &pCD );
1834 int n = FindSampler( samplerId );
1835 // if ( pCD ){
1836 if ( n >= 0 ){
1837 // SwitchSampler( (Sampler*)(pCD->Create(0)) );
1838 SetSamplerIndx( n );
1839 return TRUE;
1840 }
1841 return FALSE;
1842 }
1843
1844
1845
SetPixelSampler(Sampler * sampler)1846 void XRayMtl::SetPixelSampler( Sampler * sampler )
1847 {
1848 BOOL on = pixelSampler? pixelSampler->GetEnable() : FALSE;
1849 BOOL superTex = pixelSampler? pixelSampler->GetTextureSuperSampleOn() : TRUE;
1850 float quality = pixelSampler? pixelSampler->GetQuality() : 0.5f;
1851 ReplaceReference( SAMPLER_REF, sampler );
1852 NotifyDependents(FOREVER, 0, REFMSG_SUBANIM_STRUCTURE_CHANGED);
1853 if(pixelSampler) {
1854 pixelSampler->SetEnable( on );
1855 pixelSampler->SetTextureSuperSampleOn( superTex );
1856 pixelSampler->SetQuality( quality );
1857 }
1858 }
1859
1860 static TCHAR dots[] = _T(". . . . . . . . . . . . . . . . . . . . . . . .");
1861
UpdateTexmaps()1862 void XRayMtl::UpdateTexmaps()
1863 {
1864 // if the UI is up for the maps paramblock, adjust button text and enables
1865 // according to current shader's capabilities
1866 // UI controls are updated indirectly via calls on the ParamMap2.
1867 // further, a Param Alias table is set up for all the pmap Tab<> params for scripter access
1868 IParamMap2* pmap = pb_maps->GetMap();
1869 Shader* pShader = GetShader();
1870 long nShaderMapChannels = pShader->nTexChannelsSupported();
1871 long nMtlMapChannels = MTL_NTEXMAPS;
1872 pb_maps->ClearParamAliases();
1873 int slevChan = pShader->StdIDToChannel( ID_SS );
1874
1875 for ( long i = 0; i < STD2_NMAX_TEXMAPS; ++i )
1876 {
1877 if ( i < nShaderMapChannels )
1878 {
1879 BOOL isSupported = ! (pShader->ChannelType( i ) & UNSUPPORTED_CHANNEL);
1880 if (pmap != NULL)
1881 {
1882 TSTR chanName = maps->txmap[i].name = pShader->GetTexChannelName(i);
1883 // append dots
1884 int n = chanName.length();
1885 chanName.append( _T(" " ) );
1886 chanName.append( &dots[ n+1 ] );
1887 pmap->SetText(std2_map_enables, chanName, i);
1888 pmap->Enable(std2_map_enables, isSupported, i);
1889 pmap->Enable(std2_map_amnts, isSupported, i);
1890 pmap->Enable(std2_maps, isSupported, i);
1891
1892 if ( i == slevChan || pShader->ChannelType( i ) == SLEV_CHANNEL )
1893 pmap->SetRange(std2_map_amnts, -999, 999, i);
1894 else
1895 pmap->SetRange(std2_map_amnts, 0, 100, i);
1896
1897 }
1898 // set up the Tab<> param aliases
1899 TSTR chanIntName = pShader->GetTexChannelInternalName(i);
1900 if (chanIntName.Length() > 0)
1901 {
1902 channelTypes[ i ] = pShader->ChannelType( i );
1903 pb_maps->DefineParamAlias(chanIntName, std2_maps, i);
1904 pb_maps->DefineParamAlias(chanIntName + _T("Enable"), std2_map_enables, i); // JBW 5/24/99, made non-localizable (as names s/b internal)
1905 pb_maps->DefineParamAlias(chanIntName + _T("Amount"), std2_map_amnts, i);
1906 }
1907 }
1908 else
1909 { // beyond the end of supported shader channels
1910 if (pmap != NULL)
1911 {
1912 // add the mtls texture channels
1913 if ( nMtlMapChannels > 0 ) {
1914 TSTR chanName = maps->txmap[i].name = GetString( mtlChannelNameIDS[ i - nShaderMapChannels ] );
1915 // append dots
1916 int n = chanName.length();
1917 chanName.append( _T(" " ) );
1918 chanName.append( &dots[ n+1 ] );
1919 pmap->SetText(std2_map_enables, chanName, i);
1920 pmap->Enable(std2_map_enables, TRUE, i);
1921 pmap->Enable(std2_map_amnts, TRUE, i);
1922 pmap->Enable(std2_maps, TRUE, i);
1923 // range, first channel is bumps, last is displacement
1924 if ( nMtlMapChannels == MTL_NTEXMAPS || nMtlMapChannels == 1 )
1925 pmap->SetRange(std2_map_amnts, -999, 999, i);
1926 else
1927 pmap->SetRange(std2_map_amnts, 0, 100, i);
1928
1929 --nMtlMapChannels;
1930
1931 } else {
1932 // channel is not used for this mtl/shader
1933 pmap->SetText(std2_map_enables, dots, i);
1934 macroRecorder->Disable();
1935 SetTexmapAmt(i, 0.0f, 0);
1936 macroRecorder->Enable();
1937 pmap->Enable(std2_map_enables, FALSE, i);
1938 pmap->Enable(std2_map_amnts, FALSE, i);
1939 pmap->Enable(std2_maps, FALSE, i);
1940 }
1941 }
1942 TSTR chanIntName = mtlChannelInternalNames[ i - nShaderMapChannels ] ;
1943 if (chanIntName.Length() > 0)
1944 {
1945 channelTypes[ i ] = mtlChannelType[ i - nShaderMapChannels ];
1946 pb_maps->DefineParamAlias(chanIntName, std2_maps, i);
1947 pb_maps->DefineParamAlias(chanIntName + GetString(IDS_JW_ENABLE), std2_map_enables, i);
1948 pb_maps->DefineParamAlias(chanIntName + GetString(IDS_JW_AMOUNT), std2_map_amnts, i);
1949 }
1950
1951 }
1952 }
1953
1954 // last do the Channel Ids from stdMat
1955 for ( i = 0; i < N_ID_CHANNELS; ++i ){
1956 int chan = pShader->StdIDToChannel(i);
1957 if ( chan >= 0 ) {
1958 stdIDToChannel[i] = chan;
1959 } else if (mtlStdIDToChannel[ i ] >= 0){
1960 stdIDToChannel[i] = mtlStdIDToChannel[ i ] + pShader->nTexChannelsSupported();
1961 } else
1962 stdIDToChannel[i] = -1;
1963 }
1964
1965 // disable for old metal
1966 ULONG stdParms = pShader->SupportStdParams();
1967 if ( (stdParms & STD_BASIC2_DLG) && (stdParms & STD_PARAM_METAL) ){
1968 //metal std shader, turn off stuff
1969 int n = stdIDToChannel[ ID_SP ];
1970 if ( pmap ) {
1971 pmap->Enable(std2_map_amnts, FALSE, n );
1972 pmap->Enable(std2_maps, FALSE, n);
1973 pmap->Enable(std2_map_enables, FALSE, n);
1974 }
1975 }
1976 // disable filter on additive/subtractive
1977 if ( (stdParms & STD_EXTRA_DLG) && TRANSP_FILTER != GetTransparencyType() ){
1978 //metal std shader, turn off stuff
1979 int n = stdIDToChannel[ ID_FI ];
1980 if ( pmap ) {
1981 pmap->Enable(std2_map_amnts, FALSE, n );
1982 pmap->Enable(std2_maps, FALSE, n);
1983 pmap->Enable(std2_map_enables, FALSE, n);
1984 }
1985 }
1986
1987 }
1988
1989 static TCHAR* mapStates[] = { _T(" "), _T("m"), _T("M") };
1990
UpdateMapButtons()1991 void XRayMtl::UpdateMapButtons()
1992 {
1993 UpdateTexmaps();
1994 if (IsShaderInUI()){
1995 pShader->GetParamDlg()->UpdateMapButtons();
1996 UpdateLockADTex(TRUE);
1997 }
1998 // UpdateExtendedMapButtons();
1999 }
2000
UpdateExtendedMapButtons()2001 void XRayMtl::UpdateExtendedMapButtons()
2002 {
2003 IParamMap2* pmap = pb_extended->GetMap();
2004 if (pmap != NULL){
2005 int filtChan = stdIDToChannel[ID_FI];
2006 int state = GetMapState( filtChan );
2007 pmap->SetText(std2_ep_filter_map, mapStates[ state ]);
2008
2009 TSTR nm = GetMapName( filtChan );
2010 pmap->SetTooltip(std2_ep_filter_map, TRUE, nm);
2011 }
2012 }
2013
UpdateSamplingParams()2014 void XRayMtl::UpdateSamplingParams()
2015 {
2016 IParamMap2* map = pb_sampling->GetMap();
2017 if ( map ) {
2018 HWND hwnd = map->GetHWnd();
2019 BOOL qualityOn = pixelSampler->SupportsQualityLevels()>0 ? TRUE:FALSE ;
2020 map->Show(std2_ssampler_qual, qualityOn );
2021 HWND hwQual = GetDlgItem( hwnd, IDC_QUALITY_TEXT );
2022 ShowWindow( hwQual, qualityOn );
2023
2024 ULONG samplerParms = pixelSampler->SupportsStdParams();
2025 map->Show(std2_ssampler_adapt_on, samplerParms & ADAPTIVE_CHECK_BOX );
2026 map->Enable(std2_ssampler_adapt_threshold, pixelSampler->IsAdaptiveOn() );
2027 map->Show(std2_ssampler_adapt_threshold, samplerParms & ADAPTIVE_THRESHOLD );
2028
2029 map->Show(std2_ssampler_subsample_tex_on, samplerParms & SUPER_SAMPLE_TEX_CHECK_BOX );
2030 HWND hwThresh = GetDlgItem( hwnd, IDC_ADAPT_STATIC );
2031 ShowWindow( hwThresh, samplerParms & ADAPTIVE_THRESHOLD?TRUE:FALSE );
2032 map->Show(std2_ssampler_advanced, samplerParms & ADVANCED_DLG_BUTTON );
2033 SetDlgItemText( hwnd, IDC_COMMENT_TEXT, pixelSampler->GetDefaultComment() );
2034
2035 map->Show(std2_ssampler_param0, samplerParms & OPTIONAL_PARAM_0 );
2036 if( samplerParms & OPTIONAL_PARAM_0 )
2037 SetDlgItemText( hwnd, IDC_PARAM0_TEXT, pixelSampler->GetOptionalParamName(0) );
2038 ShowWindow( GetDlgItem( hwnd, IDC_PARAM0_TEXT ), samplerParms & OPTIONAL_PARAM_0 );
2039
2040 map->Show(std2_ssampler_param1, samplerParms & OPTIONAL_PARAM_1 );
2041 if( samplerParms & OPTIONAL_PARAM_1 )
2042 SetDlgItemText( hwnd, IDC_PARAM1_TEXT, pixelSampler->GetOptionalParamName(1) );
2043 ShowWindow( GetDlgItem( hwnd, IDC_PARAM1_TEXT ), samplerParms & OPTIONAL_PARAM_1 );
2044 }
2045 }
2046
2047 // enable & disable extra params possibly overridden by the shader
UpdateExtraParams(ULONG stdParams)2048 void XRayMtl::UpdateExtraParams( ULONG stdParams )
2049 {
2050 // update shader dlg map buttons
2051 IParamMap2* pmap = pb_extended->GetMap();
2052 if (pmap != NULL)
2053 {
2054 HWND hRollup = pmap->GetHWnd();
2055 BOOL opacOn = ( stdParams & STD_EXTRA_OPACITY ) ? TRUE : FALSE;
2056 pmap->Show( std2_opacity_type, opacOn );
2057 pmap->Show( std2_falloff_type, opacOn );
2058 pmap->Show( std2_falloff_amnt, opacOn );
2059 ShowWindow( GetDlgItem(hRollup, IDC_OPAC_TEXT1), opacOn );
2060 ShowWindow( GetDlgItem(hRollup, IDC_OPAC_TEXT2), opacOn );
2061 ShowWindow( GetDlgItem(hRollup, IDC_OPAC_TEXT3), opacOn );
2062 ShowWindow( GetDlgItem(hRollup, IDC_FILTER_OVERLAY), !opacOn );
2063
2064 BOOL reflOn = ( stdParams & STD_EXTRA_REFLECTION) ? TRUE : FALSE;
2065 pmap->Show( std2_apply_refl_dimming, reflOn );
2066 pmap->Show( std2_dim_lvl, reflOn );
2067 pmap->Show( std2_refl_lvl, reflOn );
2068 ShowWindow( GetDlgItem(hRollup, IDC_REFL_TEXT1), reflOn );
2069 ShowWindow( GetDlgItem(hRollup, IDC_REFL_TEXT2), reflOn );
2070 ShowWindow( GetDlgItem(hRollup, IDC_REFL_BOX), reflOn );
2071 // EnableWindow( GetDlgItem(hRollup, IDC_REFL_BOX), reflOn );
2072
2073 BOOL refrOn = ( stdParams & STD_EXTRA_REFRACTION ) ? TRUE : FALSE;
2074 pmap->Show( std2_ior, refrOn );
2075 ShowWindow( GetDlgItem(hRollup, IDC_REFR_TEXT1), refrOn );
2076
2077 // BOOL filterOn = (refrOn || opacOn) && GetTransparencyType() == TRANSP_FILTER;
2078 BOOL filterOn = (refrOn && !opacOn) || (opacOn && GetTransparencyType() == TRANSP_FILTER);
2079 pmap->Show( std2_filter_color, filterOn );
2080 pmap->Show( std2_ep_filter_map, filterOn );
2081 EnableWindow( GetDlgItem(hRollup, IDC_OPAC_BOX), (refrOn || opacOn) );
2082 }
2083 }
2084
GetMapState(int nMap)2085 int XRayMtl::GetMapState( int nMap )
2086 {
2087 Texmap *t = (*maps)[nMap].map;
2088 if ( t == NULL ) return 0;
2089 return (*maps)[nMap].mapOn ? 2 :1;
2090 }
2091
2092
GetMapName(int nMap)2093 TSTR XRayMtl::GetMapName( int nMap )
2094 {
2095 Texmap *t = (*maps)[nMap].map;
2096 if ( t == NULL )
2097 return TSTR( GetString( IDS_KE_NONE ) );
2098 return t->GetFullName();
2099 }
2100
2101
SyncADTexLock(BOOL lockOn)2102 void XRayMtl::SyncADTexLock( BOOL lockOn )
2103 {
2104 pb_maps->SetValue(std2_mp_ad_texlock, 0, lockOn );
2105 UpdateLockADTex(FALSE);
2106 // SetFlag( NEWSTDMTL_LOCK_ADTEX, lockOn );
2107 // force an update
2108 // if (masterDlg)
2109 // masterDlg->ReloadDialog();
2110 }
2111
UpdateLockADTex(BOOL passOn)2112 void XRayMtl::UpdateLockADTex( BOOL passOn )
2113 {
2114 IParamMap2* pmap = pb_maps->GetMap();
2115 int lock = GetFlag(NEWSTDMTL_LOCK_ADTEX)!=0;
2116 if ( pShader->SupportStdParams() & STD_PARAM_LOCKADTEX ) {
2117 if ( passOn ){
2118 pShader->SetLockADTex( lock );
2119 if (pmap != NULL && pShader->GetParamDlg())
2120 pShader->GetParamDlg()->LoadDialog(TRUE);
2121 }
2122 if (pmap != NULL)
2123 {
2124 pmap->Show(std2_mp_ad_texlock, TRUE);
2125 pmap->Enable(std2_maps, !lock, 0);
2126 }
2127 } else {
2128 // no std params, so no amb/diff lock
2129 if (pmap != NULL)
2130 {
2131 pmap->Show(std2_mp_ad_texlock, FALSE);
2132 pmap->Enable(std2_maps, TRUE, 0);
2133 }
2134 }
2135
2136 }
2137
UpdateMtlDisplay()2138 void XRayMtl::UpdateMtlDisplay()
2139 {
2140 IParamMap2* map = pb_maps->GetMap();
2141 if (map != NULL)
2142 {
2143 // removed to avoid multiple viewport redraws on change shader
2144 // map->RedrawViews(GetCOREInterface()->GetTime());
2145 map->Invalidate();
2146 }
2147 }
2148
2149 #define LIMIT0_1(x) if (x<0.0f) x = 0.0f; else if (x>1.0f) x = 1.0f;
2150 #define LIMIT1(x) if (x > 1.0f) x = 1.0f;
2151 #define LIMITMINMAX(x, min, max) if (x<min) x = min; else if (x>max) x = max;
2152
LimitColor(Color c)2153 static Color LimitColor(Color c) {
2154 LIMIT0_1(c.r);
2155 LIMIT0_1(c.g);
2156 LIMIT0_1(c.b);
2157 return c;
2158 }
2159
Update(TimeValue t,Interval & valid)2160 void XRayMtl::Update(TimeValue t, Interval &valid) {
2161 Point3 p;
2162 if (!ivalid.InInterval(t)) {
2163 ivalid.SetInfinite();
2164
2165 pb_extended->GetValue(std2_filter_color, t, p, ivalid );
2166 filter = LimitColor(Color(p.x, p.y, p.z));
2167 pb_extended->GetValue(std2_ior, t, ioRefract, ivalid );
2168 pb_extended->GetValue(std2_opacity, t, opacity, ivalid );
2169 LIMIT0_1(opacity);
2170
2171 if (IsShaderInUI())
2172 pShader->GetParamDlg()->UpdateOpacity();
2173
2174 pb_extended->GetValue(std2_falloff_amnt, t, opfall, ivalid );
2175 LIMIT0_1(opfall);
2176
2177 pb_extended->GetValue(std2_wire_size, t, wireSize, ivalid );
2178 pb_extended->GetValue(std2_dim_lvl, t, dimIntens, ivalid );
2179 LIMIT0_1(dimIntens);
2180 pb_extended->GetValue(std2_refl_lvl, t, dimMult, ivalid );
2181
2182 SetFlag(NEWSTDMTL_WIRE, pb_shader->GetInt(std2_wire, t));
2183 SetFlag(NEWSTDMTL_2SIDE, pb_shader->GetInt(std2_two_sided, t));
2184 SetFlag(NEWSTDMTL_FACEMAP, pb_shader->GetInt(std2_face_map, t));
2185 SetFlag(NEWSTDMTL_FACETED, pb_shader->GetInt(std2_faceted, t));
2186
2187 SetFlag(NEWSTDMTL_ADD_TRANSP, pb_extended->GetInt(std2_opacity_type, t) == 2);
2188 SetFlag(NEWSTDMTL_FILT_TRANSP, pb_extended->GetInt(std2_opacity_type, t) == 0);
2189 SetFlag(NEWSTDMTL_FALLOFF_OUT, pb_extended->GetInt(std2_falloff_type, t) == 1);
2190 SetFlag(NEWSTDMTL_WIRE_UNITS, pb_extended->GetInt(std2_wire_units, t) == 1);
2191 SetFlag(NEWSTDMTL_LOCK_ADTEX, pb_maps->GetInt(std2_mp_ad_texlock, t) == 1);
2192 dimReflect = pb_extended->GetInt(std2_apply_refl_dimming, t);
2193
2194 if (pShader)
2195 pShader->Update( t, ivalid );
2196
2197 for (int i = 0; i < STD2_NMAX_TEXMAPS; i++)
2198 if (MAPACTIVE(i))
2199 maps->txmap[i].Update(t, ivalid);
2200
2201 }
2202 valid &= ivalid;
2203 }
2204
AmtKeyAtTime(int i,TimeValue t)2205 BOOL XRayMtl::AmtKeyAtTime(int i, TimeValue t) {
2206 if (maps->txmap[i].amtCtrl)
2207 return maps->txmap[i].amtCtrl->IsKeyAtTime(t,0);
2208 else
2209 return FALSE;
2210 }
2211
2212 typedef struct {
2213 float amount;
2214 Control *amtCtrl;
2215 Texmap *map;
2216 BOOL mapOn;
2217 TSTR name;
2218 } saveChan;
2219
ShuffleTexMaps(Shader * newShader,Shader * oldShader)2220 void XRayMtl::ShuffleTexMaps( Shader* newShader, Shader* oldShader )
2221 {
2222 saveChan oldMaps[STD2_NMAX_TEXMAPS];
2223
2224 for( long i = 0; i < STD2_NMAX_TEXMAPS; ++i ){
2225 oldMaps[i].amtCtrl = maps->txmap[i].amtCtrl; maps->txmap[i].amtCtrl = NULL;
2226 oldMaps[i].amount = maps->txmap[i].amount; maps->txmap[i].amount = 1.0f;
2227 oldMaps[i].map = maps->txmap[i].map; maps->txmap[i].map = NULL;
2228 oldMaps[i].mapOn = maps->txmap[i].mapOn; maps->txmap[i].mapOn = FALSE;
2229 oldMaps[i].name = maps->txmap[i].name; maps->txmap[i].name = _T("");
2230 }
2231 int nOldShadeMaps = oldShader->nTexChannelsSupported();
2232 int nNewShadeMaps = newShader->nTexChannelsSupported();
2233
2234 // for each new shader map
2235 for( int oldChan, newChan = 0; newChan < nNewShadeMaps; ++newChan ){
2236
2237 TSTR newName = newShader->GetTexChannelInternalName(newChan);
2238
2239 // look for match in each old map
2240 for ( oldChan = 0; oldChan < nOldShadeMaps; ++oldChan ) {
2241 if ( newName == oldShader->GetTexChannelInternalName(oldChan) )
2242 break;
2243 }
2244
2245 if( oldChan < nOldShadeMaps ) { // found it
2246 maps->txmap[newChan].amtCtrl = oldMaps[oldChan].amtCtrl;
2247 maps->txmap[newChan].amount = oldMaps[oldChan].amount;
2248 maps->txmap[newChan].map = oldMaps[oldChan].map;
2249 maps->txmap[newChan].mapOn = oldMaps[oldChan].mapOn;
2250 maps->txmap[newChan].name = oldMaps[oldChan].name;
2251 }
2252
2253 }// end, for each new map
2254
2255 // now do the mtl maps
2256 for ( int n = 0; n < MTL_NTEXMAPS; ++n ){
2257 newChan = n + nNewShadeMaps;
2258 oldChan = n + nOldShadeMaps;
2259 maps->txmap[newChan].amtCtrl = oldMaps[oldChan].amtCtrl;
2260 maps->txmap[newChan].amount = oldMaps[oldChan].amount;
2261 maps->txmap[newChan].map = oldMaps[oldChan].map;
2262 maps->txmap[newChan].mapOn = oldMaps[oldChan].mapOn;
2263 maps->txmap[newChan].name = oldMaps[oldChan].name;
2264 }
2265 }
2266
ShuffleShaderParams(Shader * newShader,Shader * oldShader)2267 void XRayMtl::ShuffleShaderParams( Shader* newShader, Shader* oldShader )
2268 {
2269 ClassDesc2 *oldCD2 = NULL, *newCD2 = NULL;
2270
2271 ClassDesc * newCD;
2272 FindShader( newShader->ClassID(), &newCD );
2273
2274 ClassDesc * oldCD;
2275 FindShader( oldShader->ClassID(), &oldCD );
2276
2277 // check if we have a ParamBlock2-based shaders
2278 if (oldCD != NULL && oldCD->InternalName() != NULL)
2279 oldCD2 = (ClassDesc2*)oldCD;
2280 if (newCD != NULL && newCD->InternalName() != NULL)
2281 newCD2 = (ClassDesc2*)newCD;
2282
2283 // loop over destination shaders PB2-based parameters
2284 if (oldCD2 != NULL && newCD2 != NULL){
2285 // loop over each block in the new shader
2286 for (int i = 0; i < newCD2->NumParamBlockDescs(); i++){
2287 // get block descriptor and source paramblock
2288 ParamBlockDesc2* newPBdesc = newCD2->GetParamBlockDesc(i);
2289 IParamBlock2* newPB2 = newShader->GetParamBlockByID(newPBdesc->ID);
2290 // loop over each new param and copy from old if there's a match
2291 for (int j = 0; j < newPBdesc->count; j++){
2292 ParamDef& paramDef = newPBdesc->paramdefs[j];
2293
2294 // Now search the old shaders blocks
2295 for (int i = 0; i < oldCD2->NumParamBlockDescs(); i++){
2296 ParamBlockDesc2* oldPBdesc = oldCD2->GetParamBlockDesc(i);
2297 int j = oldPBdesc->NameToIndex(paramDef.int_name);
2298 if (j >= 0){
2299 // found an internal name match, get the dest pblock and param def
2300 ParamDef& srcParamDef = oldPBdesc->paramdefs[j];
2301 // copy only if types match
2302 if (srcParamDef.type == paramDef.type){
2303 IParamBlock2* oldPB2 = oldShader->GetParamBlockByID(oldPBdesc->ID);
2304 newPB2->Assign(paramDef.ID, oldPB2, srcParamDef.ID);
2305 goto nextParam; // found it, outta here...
2306 }
2307
2308 }
2309 }
2310 nextParam: ;
2311 }// end, dest param loop
2312 }// end, desk block loop
2313 Interval v;
2314 v.SetInfinite();
2315 newShader->Update(0, v);
2316
2317 // end, pb2 copying
2318 } else {
2319
2320 // StdParam based copy
2321 newShader->CopyStdParams( oldShader );
2322 }
2323 }
2324
GetXParency(int mtlNum,BOOL backFace)2325 float XRayMtl::GetXParency(int mtlNum, BOOL backFace) {
2326 int opacChan = stdIDToChannel[ ID_OP ];
2327
2328 // When the mtl has "Show Map in Viewport" turned on, and has an opacity map,
2329 // the opacity map over-rides the opacity. DS 6/16/00
2330 // (Actually, when the hardward doesn't support enough texture channels to do
2331 // the opacity map, the overide is only true for NON-decal maps).
2332 //
2333 if (((*maps)[opacChan].map&&MAPACTIVE(opacChan)&&Active())) {
2334 return 0.0f;
2335 }
2336
2337 // The following statement looks dubious -- what is it trying to do? -- DS 6/16/00
2338 if(opacity>0.9f && opfall>0.0f)
2339 return 0.1f;
2340 else
2341 return 1.0f-opacity;
2342 }
2343
Requirements(int subMtlNum)2344 ULONG XRayMtl::Requirements(int subMtlNum) {
2345 ULONG req;
2346
2347 assert( pShader );
2348 req = pShader->GetRequirements(subMtlNum);
2349
2350 int opacChan = stdIDToChannel[ ID_OP ];
2351 int bumpChan = stdIDToChannel[ ID_BU ];
2352 int dispChan = stdIDToChannel[ ID_DP ];
2353
2354 if (opacity!=1.0f||MAPACTIVE(opacChan)||opfall>0.0f) {
2355 req |= MTLREQ_TRANSP;
2356 }
2357
2358 if (opacity!=1.0f|| ((*maps)[opacChan].map&&MAPACTIVE(opacChan)&&Active()))
2359 req |= MTLREQ_TRANSP_IN_VP;
2360
2361 for (int i=0; i<STD2_NMAX_TEXMAPS; i++) {
2362 if (MAPACTIVE(i))
2363 req |= (*maps)[i].map->Requirements(subMtlNum);
2364 }
2365 if (MAPACTIVE(bumpChan)) {
2366 ULONG bmpreq = (*maps)[bumpChan].map->Requirements(subMtlNum);
2367 if (bmpreq&MTLREQ_UV)
2368 req |= MTLREQ_BUMPUV;
2369 if (bmpreq&MTLREQ_UV2)
2370 req |= MTLREQ_BUMPUV2;
2371 }
2372 if (flags&NEWSTDMTL_WIRE) req|= MTLREQ_WIRE;
2373 if (flags&NEWSTDMTL_2SIDE) req|= MTLREQ_2SIDE;
2374 // if (pixelSampler && pixelSampler->GetEnable() )
2375 if ( flags&NEWSTDMTL_SSAMP_ON )
2376 req|= MTLREQ_SUPERSAMPLE;
2377 if (flags&NEWSTDMTL_WIRE_UNITS) req|= MTLREQ_WIRE_ABS;
2378 if (flags&NEWSTDMTL_FACEMAP) req |= MTLREQ_FACEMAP;
2379 if (flags&NEWSTDMTL_ADD_TRANSP) req |= MTLREQ_ADDITIVE_TRANSP;
2380 if (flags&NEWSTDMTL_FACETED) req |= MTLREQ_FACETED;
2381 if (MAPACTIVE(dispChan)) req |= MTLREQ_DISPLACEMAP;
2382 return req;
2383 }
2384
MapSlotType(int i)2385 int XRayMtl::MapSlotType(int i)
2386 {
2387 if (i==stdIDToChannel[ID_DP]) return MAPSLOT_DISPLACEMENT; // DS 4/12/99
2388 return (i==stdIDToChannel[ID_RL] || i==stdIDToChannel[ID_RR])?
2389 MAPSLOT_ENVIRON : MAPSLOT_TEXTURE;
2390 }
2391
MappingsRequired(int subMtlNum,BitArray & mapreq,BitArray & bumpreq)2392 void XRayMtl::MappingsRequired(int subMtlNum, BitArray & mapreq, BitArray &bumpreq) {
2393 int bumpChan = stdIDToChannel[ ID_BU ];
2394 for (int i=0; i<STD2_NMAX_TEXMAPS; i++) {
2395 if (MAPACTIVE(i)) {
2396 if (i==bumpChan)
2397 (*maps)[i].map->MappingsRequired(subMtlNum,bumpreq,bumpreq);
2398 else
2399 (*maps)[i].map->MappingsRequired(subMtlNum,mapreq,bumpreq);
2400 }
2401 }
2402 }
2403
Validity(TimeValue t)2404 Interval XRayMtl::Validity(TimeValue t) {
2405 Interval v;
2406 Update(t, v);
2407 return ivalid;
2408 }
2409
NotifyChanged()2410 void XRayMtl::NotifyChanged() {
2411 NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
2412 }
2413
SetFlag(ULONG f,ULONG val)2414 void XRayMtl::SetFlag(ULONG f, ULONG val) {
2415 if (val) flags|=f;
2416 else flags &= ~f;
2417 }
2418
SetTransparencyType(int type)2419 void XRayMtl::SetTransparencyType(int type) {
2420 switch (type) {
2421 case TRANSP_SUBTRACTIVE:
2422 SetFlag(NEWSTDMTL_ADD_TRANSP, 0);
2423 SetFlag(NEWSTDMTL_FILT_TRANSP, 0);
2424 pb_extended->SetValue(std2_opacity_type, 0, 1);
2425 break;
2426 case TRANSP_ADDITIVE:
2427 SetFlag(NEWSTDMTL_ADD_TRANSP, 1);
2428 SetFlag(NEWSTDMTL_FILT_TRANSP, 0);
2429 pb_extended->SetValue(std2_opacity_type, 0, 2);
2430 break;
2431 case TRANSP_FILTER:
2432 SetFlag(NEWSTDMTL_ADD_TRANSP, 0);
2433 SetFlag(NEWSTDMTL_FILT_TRANSP, 1);
2434 pb_extended->SetValue(std2_opacity_type, 0, 0);
2435 break;
2436 }
2437 }
2438
DeleteThis()2439 void XRayMtl::DeleteThis()
2440 {
2441 delete this;
2442 }
2443
2444
SubAnimName(int i)2445 TSTR XRayMtl::SubAnimName(int i) {
2446 switch(i){
2447 case TEXMAPS_SUB: return TSTR(GetString( IDS_DS_TEXMAPS ));
2448 case SHADER_SUB: return TSTR(GetString( IDS_KE_SHADER ));
2449 case EXTRA_PB_SUB: return TSTR(GetString( IDS_DS_EXTRA ));
2450 case SAMPLING_PB_SUB: return TSTR(GetString( IDS_KE_SAMPLING ));
2451 case DYNAMICS_PB_SUB: return TSTR(GetString( IDS_DS_DYNAMICS ));
2452 }
2453 return TSTR("");
2454 }
2455
SubAnim(int i)2456 Animatable* XRayMtl::SubAnim(int i) {
2457 switch(i) {
2458 case TEXMAPS_SUB: return maps;
2459 case SHADER_SUB: return pShader;
2460 case EXTRA_PB_SUB: return pb_extended;
2461 case SAMPLING_PB_SUB: return pb_sampling;
2462 case DYNAMICS_PB_SUB: return pb_dynamics;
2463 default: DbgAssert(0); return NULL;
2464 }
2465 }
2466
SubNumToRefNum(int subNum)2467 int XRayMtl::SubNumToRefNum(int subNum)
2468 {
2469 switch (subNum)
2470 {
2471 case TEXMAPS_SUB: return TEXMAPS_REF;
2472 case SHADER_SUB: return SHADER_REF;
2473 case EXTRA_PB_SUB: return EXTENDED_PB_REF;
2474 case SAMPLING_PB_SUB: return SAMPLING_PB_REF;
2475 case DYNAMICS_PB_SUB: return DYNAMICS_PB_REF;
2476 default: DbgAssert(0); return 0;
2477 }
2478 }
2479
2480 IParamBlock2*
GetParamBlock(int i)2481 XRayMtl::GetParamBlock(int i)
2482 {
2483 switch (i)
2484 {
2485 case 0: return pb_shader;
2486 case 1: return pb_extended;
2487 case 2: return pb_sampling;
2488 case 3: return pb_maps;
2489 case 4: return pb_dynamics;
2490 case 5: return pb_xray;
2491 }
2492 return NULL;
2493 }
2494
2495 IParamBlock2*
GetParamBlockByID(BlockID id)2496 XRayMtl::GetParamBlockByID(BlockID id)
2497 {
2498 // return id'd ParamBlock
2499 switch (id)
2500 {
2501 case std2_shader: return pb_shader;
2502 case std2_extended: return pb_extended;
2503 case std2_sampling: return pb_sampling;
2504 case std_maps: return pb_maps;
2505 case std2_dynamics: return pb_dynamics;
2506 case std2_xray: return pb_xray;
2507 }
2508 return NULL;
2509 }
2510
GetReference(int i)2511 RefTargetHandle XRayMtl::GetReference(int i) {
2512 switch(i) {
2513 case OLD_PBLOCK_REF: return old_pblock; // old pblock, replaced by the 6 new pb2's
2514 case TEXMAPS_REF: return maps;
2515 case SHADER_REF: return pShader;
2516 case SHADER_PB_REF: return pb_shader;
2517 case EXTENDED_PB_REF: return pb_extended;
2518 case SAMPLING_PB_REF: return pb_sampling;
2519 case MAPS_PB_REF: return pb_maps;
2520 #ifndef DESIGN_VER
2521 case DYNAMICS_PB_REF: return pb_dynamics;
2522 #else
2523 case DYNAMICS_PB_REF: return NULL;
2524 #endif
2525 case XRAY_PB_REF: return pb_xray;
2526 case SAMPLER_REF: return pixelSampler;
2527 default: assert(0); return NULL;
2528 }
2529 }
2530
SetReference(int i,RefTargetHandle rtarg)2531 void XRayMtl::SetReference(int i, RefTargetHandle rtarg) {
2532 switch(i) {
2533 case OLD_PBLOCK_REF: old_pblock = (IParamBlock*)rtarg; return;
2534 case TEXMAPS_REF: {
2535 maps = (Texmaps*)rtarg;
2536 if (maps != NULL)
2537 maps->client = this;
2538 return;
2539 }
2540 case SHADER_REF:
2541 if (IsShaderInUI()){
2542 pShader->GetParamDlg()->SetThings(this, NULL);
2543 pShader->SetParamDlg(NULL);
2544 }
2545 pShader = (Shader*)rtarg;
2546
2547 return;
2548 case SHADER_PB_REF: pb_shader = (IParamBlock2*)rtarg; return;
2549 case EXTENDED_PB_REF: pb_extended = (IParamBlock2*)rtarg; return;
2550 case SAMPLING_PB_REF: pb_sampling = (IParamBlock2*)rtarg; return;
2551 case MAPS_PB_REF: pb_maps = (IParamBlock2*)rtarg; return;
2552 case DYNAMICS_PB_REF: pb_dynamics = (IParamBlock2*)rtarg; return;
2553 case XRAY_PB_REF: pb_xray = (IParamBlock2*)rtarg; return;
2554 case SAMPLER_REF: pixelSampler = (Sampler*)rtarg; return;
2555 default: assert(0);
2556 }
2557 }
2558
SetSubTexmap(int i,Texmap * m)2559 void XRayMtl::SetSubTexmap(int i, Texmap *m)
2560 {
2561 assert(i < STD2_NMAX_TEXMAPS);
2562 pb_maps->SetValue(std2_maps, TimeValue(0), m, i);
2563 }
2564
2565 // mjm - begin - 06.02.00
UpdateReshadeRequirements(RefTargetHandle hTarget,PartID partID)2566 void XRayMtl::UpdateReshadeRequirements(RefTargetHandle hTarget, PartID partID)
2567 {
2568 if (!killRefmsg.DistributeRefmsg())
2569 {
2570 mReshadeRQ = RR_None;
2571 }
2572 else if (hTarget == maps)
2573 {
2574 mReshadeRQ = RR_NeedPreshade;
2575 }
2576 else if (hTarget == pShader)
2577 {
2578 mReshadeRQ = RR_NeedReshade;
2579 }
2580 else if (hTarget == pb_xray)
2581 {
2582 mReshadeRQ = RR_None;
2583 }
2584 else if (hTarget == pb_shader)
2585 {
2586 mReshadeRQ = RR_NeedReshade;
2587 }
2588 else if (hTarget == pb_extended)
2589 {
2590 mReshadeRQ = RR_NeedReshade;
2591 }
2592 else if (hTarget == pb_sampling)
2593 {
2594 mReshadeRQ = RR_None;
2595 }
2596 else if (hTarget == pb_maps)
2597 {
2598 if ( pb_maps->LastNotifyParamID() == std2_map_amnts)
2599 mReshadeRQ = RR_NeedReshade;
2600 else
2601 mReshadeRQ = RR_NeedPreshade;
2602 }
2603 else if (hTarget == pb_dynamics)
2604 {
2605 mReshadeRQ = RR_None;
2606 }
2607 else if (hTarget == pixelSampler)
2608 {
2609 mReshadeRQ = RR_None;
2610 }
2611
2612 mReshadeRQ = chooseReshade[mReshadeRQ][mInRQ];
2613 mInRQ = RR_None;
2614 }
2615 // mjm - end
2616
2617 // invaldate for the viewport
NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget,PartID & partID,RefMessage message)2618 RefResult XRayMtl::NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget,
2619 PartID& partID, RefMessage message )
2620 {
2621 switch (message) {
2622 case REFMSG_WANT_SHOWPARAMLEVEL:
2623 {
2624 BOOL *pb = (BOOL *)(partID);
2625 *pb = TRUE;
2626 return REF_STOP;
2627 }
2628 case REFMSG_CHANGE:
2629 UpdateReshadeRequirements(hTarget, partID); // mjm - 06.02.00
2630
2631 ivalid.SetEmpty();
2632 // ask ClassDesc if any paramblock change caused the notify
2633 // if not and changing ref was one of the pblocks, inval all PB2 UI
2634 // else inval indicated param UI
2635 IParamBlock2* cpb;
2636 ParamID changing_param = stdmtl2CD.LastNotifyParamID(this, cpb);
2637 if (hTarget != pShader) // && hTarget != maps)
2638 {
2639 if (changing_param != -1)
2640 {
2641 // DS 10/13/00: I needed to add code to check of the dialog for this map was actualy active because
2642 // on during the creation of new materials, messages were getting routed to the current
2643 // medit material, causing problems for undo of sub-object mtl assignment.
2644 // DS 10/24/31: Removed the test because it isn't quite right, and was causing some problems ( #264662)
2645 // and no longer seems necessary. (we need a better test for whether a mtl is in medit or not)
2646 //if (cpb->GetMap()&&cpb->GetMap()->DlgActive()))
2647 cpb->GetDesc()->InvalidateUI(changing_param);
2648 if (changing_param == std2_opacity &&
2649 cpb == pb_extended && pShader &&
2650 pShader->GetParamDlg())
2651 pShader->GetParamDlg()->UpdateOpacity();
2652 }
2653 else
2654 {
2655 stdmtl2CD.InvalidateUI();
2656 if (hTarget == pb_extended && pShader &&
2657 pShader->GetParamDlg())
2658 pShader->GetParamDlg()->UpdateOpacity();
2659 if (texHandle[0]||texHandle[1]) {
2660 if (curImp)
2661 curImp->MtlChanged();
2662 }
2663 }
2664 DiscardTexHandles(); // DS 5/22/00
2665 }
2666 break;
2667 }
2668
2669 return REF_SUCCEED;
2670 }
2671
ClassID()2672 Class_ID XRayMtl::ClassID() { return XRAYMTL_CLASS_ID; }
2673
GetSubTexmapSlotName(int i)2674 TSTR XRayMtl::GetSubTexmapSlotName(int i) {
2675 if ( pShader ){
2676 long nShaderChan = pShader->nTexChannelsSupported();
2677 if ( i < nShaderChan )
2678 return pShader->GetTexChannelName( i );
2679 else
2680 return GetString( mtlChannelNameIDS[i - nShaderChan] );
2681 } else return TSTR("");
2682 }
2683
2684
EnableMap(int i,BOOL onoff)2685 void XRayMtl::EnableMap(int i, BOOL onoff) {
2686 pb_maps->SetValue(std2_map_enables, TimeValue(0), onoff, i);
2687 }
2688
SetFilter(Color c,TimeValue t)2689 void XRayMtl::SetFilter(Color c, TimeValue t) {
2690 filter = c;
2691 pb_extended->SetValue( std2_filter_color, t, Point3(c.r, c.g, c.b));
2692 int opacChan = stdIDToChannel[ ID_OP ];
2693 if (opacity!=1.0f||opfall!=0.0f||MAPACTIVE(opacChan))
2694 NotifyChanged();
2695 }
2696
SetIOR(float v,TimeValue t)2697 void XRayMtl::SetIOR(float v, TimeValue t) {
2698 ioRefract = v;
2699 pb_extended->SetValue(std2_ior, t, v);
2700 }
2701
SetOpacity(float v,TimeValue t)2702 void XRayMtl::SetOpacity(float v, TimeValue t) {
2703 opacity = v;
2704 pb_extended->SetValue(std2_opacity, t, v);
2705 }
2706
SetOpacFalloff(float v,TimeValue t)2707 void XRayMtl::SetOpacFalloff(float v, TimeValue t) {
2708 opfall = v;
2709 pb_extended->SetValue(std2_falloff_amnt, t, v);
2710 int opacChan = stdIDToChannel[ ID_OP ];
2711 if (opacity!=1.0f||opfall!=0.0f||MAPACTIVE(opacChan))
2712 NotifyChanged();
2713 }
2714
SetWireSize(float v,TimeValue t)2715 void XRayMtl::SetWireSize(float v, TimeValue t) {
2716 wireSize = v;
2717 pb_extended->SetValue(std2_wire_size, t, v);
2718 if (flags&NEWSTDMTL_WIRE)
2719 NotifyChanged();
2720 }
2721
SetDimIntens(float v,TimeValue t)2722 void XRayMtl::SetDimIntens(float v, TimeValue t) {
2723 dimIntens = v;
2724 pb_extended->SetValue(std2_dim_lvl, t, v);
2725 }
2726
SetDimMult(float v,TimeValue t)2727 void XRayMtl::SetDimMult(float v, TimeValue t) {
2728 dimMult = v;
2729 pb_extended->SetValue(std2_refl_lvl, t, v);
2730 }
2731
SetTexmapAmt(int imap,float amt,TimeValue t)2732 void XRayMtl::SetTexmapAmt(int imap, float amt, TimeValue t) {
2733 pb_maps->SetValue(std2_map_amnts, t, amt, imap);
2734 }
2735
2736 /////////////////////////////////////////////////////////////////////
2737 // shaders
SetShaderIndx(long indx,BOOL update)2738 void XRayMtl::SetShaderIndx( long indx, BOOL update )
2739 {
2740 if( !update ) shaderId = NO_UPDATE;
2741 pb_shader->SetValue(std2_shader_type, 0, indx<0 ? 0 : indx );
2742 shaderId = indx;
2743 }
2744
SetSamplerIndx(long indx,BOOL update)2745 void XRayMtl::SetSamplerIndx( long indx, BOOL update )
2746 {
2747 if( !update ) samplerId = NO_UPDATE;
2748 pb_sampling->SetValue(std2_ssampler, 0, indx<0 ? 0 : indx );
2749 samplerId = indx;
2750 }
2751
2752
2753 static Class_ID ClassID0(0, 0);
2754 static Class_ID ClassID1(1, 0);
2755
SetShader(Shader * pNewShader)2756 void XRayMtl::SetShader( Shader* pNewShader )
2757 {
2758 // if ( (pShader?pShader->ClassID():ClassID0) != (pNewShader?pNewShader->ClassID():ClassID1) ){
2759 ReplaceReference( SHADER_REF, pNewShader );
2760 NotifyChanged();
2761 NotifyDependents(FOREVER, 0, REFMSG_SUBANIM_STRUCTURE_CHANGED);
2762 // }
2763 }
2764
2765 // the shader Gets & Sets
IsSelfIllumColorOn()2766 BOOL XRayMtl::IsSelfIllumColorOn()
2767 { if (pShader->SupportStdParams() & STD_PARAM_SELFILLUM_CLR){
2768 return pShader->IsSelfIllumClrOn();
2769 }
2770 return FALSE;
2771 }
2772
SetSelfIllumColorOn(BOOL on)2773 void XRayMtl::SetSelfIllumColorOn( BOOL on )
2774 { if (pShader->SupportStdParams() & STD_PARAM_SELFILLUM_CLR){
2775 pShader->SetSelfIllumClrOn( on );
2776 }
2777 }
2778
SetAmbient(Color c,TimeValue t)2779 void XRayMtl::SetAmbient(Color c, TimeValue t)
2780 { if (pShader->SupportStdParams() & STD_PARAM_AMBIENT_CLR){
2781 pShader->SetAmbientClr( c, t );
2782 }
2783 }
2784
SetDiffuse(Color c,TimeValue t)2785 void XRayMtl::SetDiffuse(Color c, TimeValue t)
2786 { if (pShader->SupportStdParams() & STD_PARAM_DIFFUSE_CLR){
2787 pShader->SetDiffuseClr( c, t );
2788 }
2789 }
2790
SetSpecular(Color c,TimeValue t)2791 void XRayMtl::SetSpecular(Color c, TimeValue t)
2792 { if (pShader->SupportStdParams() & STD_PARAM_SPECULAR_CLR){
2793 pShader->SetSpecularClr( c, t );
2794 }
2795 }
2796
SetShininess(float v,TimeValue t)2797 void XRayMtl::SetShininess(float v, TimeValue t)
2798 { if (pShader->SupportStdParams() & STD_PARAM_GLOSSINESS ){
2799 pShader->SetGlossiness( v, t );
2800 }
2801 }
2802
SetShinStr(float v,TimeValue t)2803 void XRayMtl::SetShinStr(float v, TimeValue t)
2804 { if (pShader->SupportStdParams() & STD_PARAM_SPECULAR_LEV ){
2805 pShader->SetSpecularLevel( v, t );
2806 }
2807 }
2808
SetSelfIllum(float v,TimeValue t)2809 void XRayMtl::SetSelfIllum(float v, TimeValue t)
2810 { if (pShader->SupportStdParams() & STD_PARAM_SELFILLUM ){
2811 pShader->SetSelfIllum( v, t );
2812 }
2813 }
2814
2815
SetSelfIllumColor(Color c,TimeValue t)2816 void XRayMtl::SetSelfIllumColor(Color c, TimeValue t)
2817 { if (pShader->SupportStdParams() & STD_PARAM_SELFILLUM_CLR){
2818 pShader->SetSelfIllumClr( c, t );
2819 }
2820 }
2821
2822 static Color blackClr( 0.0, 0.0, 0.0 );
2823
GetAmbient(int mtlNum,BOOL backFace)2824 Color XRayMtl::GetAmbient(int mtlNum, BOOL backFace)
2825 {
2826 return pShader->GetAmbientClr( mtlNum, backFace );
2827 }
2828
GetDiffuse(int mtlNum,BOOL backFace)2829 Color XRayMtl::GetDiffuse(int mtlNum, BOOL backFace)
2830 {
2831 return pShader->GetDiffuseClr( mtlNum, backFace );
2832 }
2833
GetSpecular(int mtlNum,BOOL backFace)2834 Color XRayMtl::GetSpecular(int mtlNum, BOOL backFace)
2835 {
2836 return pShader->GetSpecularClr( mtlNum, backFace );
2837 }
2838
GetSelfIllumColor(int mtlNum,BOOL backFace)2839 Color XRayMtl::GetSelfIllumColor(int mtlNum, BOOL backFace)
2840 {
2841 return pShader->GetSelfIllumClr( mtlNum, backFace );
2842 }
2843
2844
GetShininess(int mtlNum,BOOL backFace)2845 float XRayMtl::GetShininess(int mtlNum, BOOL backFace)
2846 {
2847 float g = pShader->GetGlossiness( mtlNum, backFace );
2848 return Bound( g, 0.01f, 1.0f );
2849 }
2850
GetShinStr(int mtlNum,BOOL backFace)2851 float XRayMtl::GetShinStr(int mtlNum, BOOL backFace)
2852 {
2853 return pShader->GetSpecularLevel( mtlNum, backFace );
2854 }
2855
GetSelfIllum(int mtlNum,BOOL backFace)2856 float XRayMtl::GetSelfIllum(int mtlNum, BOOL backFace)
2857 {
2858 return pShader->GetSelfIllum( mtlNum, backFace );
2859 }
2860
GetShininess(TimeValue t)2861 float XRayMtl::GetShininess(TimeValue t)
2862 {
2863 return pShader->GetGlossiness( t );
2864 }
2865
GetShinStr(TimeValue t)2866 float XRayMtl::GetShinStr(TimeValue t)
2867 {
2868 return pShader->GetSpecularLevel( t );
2869 }
2870
GetSelfIllum(TimeValue t)2871 float XRayMtl::GetSelfIllum(TimeValue t)
2872 {
2873 return pShader->GetSelfIllum(t);
2874 }
2875
2876
GetSelfIllumColorOn(int mtlNum,BOOL backFace)2877 BOOL XRayMtl::GetSelfIllumColorOn(int mtlNum, BOOL backFace)
2878 {
2879 return pShader->IsSelfIllumClrOn();
2880 }
2881
GetAmbient(TimeValue t)2882 Color XRayMtl::GetAmbient(TimeValue t)
2883 {
2884 return pShader->GetAmbientClr( t );
2885 }
GetDiffuse(TimeValue t)2886 Color XRayMtl::GetDiffuse(TimeValue t)
2887 {
2888 return pShader->GetDiffuseClr(t);
2889 }
GetSpecular(TimeValue t)2890 Color XRayMtl::GetSpecular(TimeValue t)
2891 {
2892 return pShader->GetSpecularClr( t );
2893 }
GetSelfIllumColor(TimeValue t)2894 Color XRayMtl::GetSelfIllumColor(TimeValue t)
2895 {
2896 return pShader->GetSelfIllumClr(t );
2897 }
2898
GetSoftenLevel(TimeValue t)2899 float XRayMtl::GetSoftenLevel( TimeValue t)
2900 {
2901 return pShader->GetSoftenLevel(t);
2902 }
2903
GetFilter()2904 Color XRayMtl::GetFilter() { return filter; }
GetTexmapAmt(int imap)2905 float XRayMtl::GetTexmapAmt(int imap) { return maps->txmap[imap].amount; }
GetTexmapAmt(int imap,TimeValue t)2906 float XRayMtl::GetTexmapAmt(int imap, TimeValue t) { return maps->txmap[imap].GetAmount(t); }
2907
GetFilter(TimeValue t)2908 Color XRayMtl::GetFilter(TimeValue t) { return pb_extended->GetColor(std2_filter_color, t); }
GetOpacity(TimeValue t)2909 float XRayMtl::GetOpacity( TimeValue t) { return pb_extended->GetFloat(std2_opacity, t); }
GetOpacFalloff(TimeValue t)2910 float XRayMtl::GetOpacFalloff(TimeValue t){ return pb_extended->GetFloat(std2_falloff_amnt, t);}
GetWireSize(TimeValue t)2911 float XRayMtl::GetWireSize(TimeValue t) { return pb_extended->GetFloat(std2_wire_size, t);}
GetIOR(TimeValue t)2912 float XRayMtl::GetIOR( TimeValue t) { return pb_extended->GetFloat(std2_ior, t);}
GetDimIntens(TimeValue t)2913 float XRayMtl::GetDimIntens( TimeValue t) { return pb_extended->GetFloat(std2_dim_lvl, t); }
GetDimMult(TimeValue t)2914 float XRayMtl::GetDimMult( TimeValue t) { return pb_extended->GetFloat(std2_refl_lvl, t); }
MapEnabled(int i)2915 BOOL XRayMtl::MapEnabled(int i) { return maps->txmap[i].mapOn;}
2916
2917
GetDynamicsProperty(TimeValue t,int mtlNum,int propID)2918 float XRayMtl::GetDynamicsProperty(TimeValue t, int mtlNum, int propID) {
2919 float val;
2920 Interval ivalid;
2921 switch(propID) {
2922 case DYN_BOUNCE:
2923 pb_dynamics->GetValue(std2_bounce, t, val, ivalid);
2924 return val;
2925 case DYN_STATIC_FRICTION:
2926 pb_dynamics->GetValue(std2_static_friction, t, val, ivalid);
2927 return val;
2928 case DYN_SLIDING_FRICTION:
2929 pb_dynamics->GetValue(std2_sliding_friction, t, val, ivalid);
2930 return val;
2931 default:
2932 assert(0);
2933 return 0.0f;
2934 }
2935 }
2936
SetDynamicsProperty(TimeValue t,int mtlNum,int propID,float value)2937 void XRayMtl::SetDynamicsProperty(TimeValue t, int mtlNum, int propID, float value){
2938 #ifndef DESIGN_VER
2939 switch(propID) {
2940 case DYN_BOUNCE:
2941 pb_dynamics->SetValue( std2_bounce, t, value);
2942 break;
2943 case DYN_STATIC_FRICTION:
2944 pb_dynamics->SetValue( std2_static_friction, t, value);
2945 break;
2946 case DYN_SLIDING_FRICTION:
2947 pb_dynamics->SetValue( std2_sliding_friction, t, value);
2948 break;
2949 default:
2950 assert(0);
2951 break;
2952 }
2953 #endif
2954 }
2955
2956 // returns the index of the shader in the list
FindShader(Class_ID & findId,ClassDesc ** ppCD)2957 int XRayMtl::FindShader( Class_ID& findId, ClassDesc** ppCD )
2958 {
2959 for (int i = 0; i < XRayMtl::NumShaders(); i++) {
2960 ClassDesc* pCD = XRayMtl::GetShaderCD(i);
2961 if ( findId == pCD->ClassID() ){
2962 if (ppCD) *ppCD = pCD;
2963 return i;
2964 }
2965 }
2966 if (ppCD) *ppCD = NULL; // not found
2967 return -1;
2968 }
2969
FindSampler(Class_ID findId,ClassDesc ** ppCD)2970 int XRayMtl::FindSampler( Class_ID findId, ClassDesc** ppCD )
2971 {
2972 for (int i = 0; i < XRayMtl::NumSamplers(); i++) {
2973 ClassDesc* pCD = XRayMtl::GetSamplerCD(i);
2974 if ( findId == pCD->ClassID() ){
2975 if (ppCD) *ppCD = pCD;
2976 return i;
2977 }
2978 }
2979 if (ppCD) *ppCD = NULL; // not found
2980 return -1;
2981 }
2982
2983 /***
2984 ClassDesc* XRayMtl::SamplerIndxToCD( int indx )
2985 {
2986 IParamMap2* map = pb_sampling ? pb_sampling->GetMap() : NULL;
2987 if ( indx < 0 ) indx = 0;
2988 if ( map ) {
2989 HWND hwnd = map->GetHWnd();
2990 HWND hwndSampler = GetDlgItem(hwnd, IDC_PIX_SAMPLER);
2991 ClassDesc* pCD = (ClassDesc*)SendMessage( hwndSampler, CB_GETITEMDATA, indx, 0 );
2992 return pCD;
2993 }
2994 // last resort
2995 SubClassList * scList = GetCOREInterface()->GetDllDir().ClassDir().GetClassList(SAMPLER_CLASS_ID);
2996 return (*scList)[ 1 ].CD();
2997 }
2998 ***/
2999
3000
3001
3002 /////////////////////////////////////////////////////////////////////////
3003 // Filing
3004 //
3005 #define MTL_HDR_CHUNK 0x4000
3006 #define NEWSTDMTL_FLAGS_CHUNK 0x5000
3007 #define NEWSTDMTL_SHADING_CHUNK 0x5004
3008 #define NEWSTDMTL_TEX_ONOFF_CHUNK 0x5002
3009 #define NEWSTDMTL_TEX_AMT0 0x5100
3010 #define NEWSTDMTL_TEX_AMT1 0x5101
3011 #define NEWSTDMTL_TEX_AMT2 0x5102
3012 #define NEWSTDMTL_TEX_AMT3 0x5103
3013 #define NEWSTDMTL_TEX_AMT4 0x5104
3014 #define NEWSTDMTL_TEX_AMT5 0x5105
3015 #define NEWSTDMTL_TEX_AMT6 0x5106
3016 #define NEWSTDMTL_TEX_AMT7 0x5107
3017 #define NEWSTDMTL_TEX_AMT8 0x5108
3018 #define NEWSTDMTL_TEX_AMT9 0x5109
3019 #define NEWSTDMTL_TEX_AMTA 0x510A
3020
3021 //xray part
3022 #define NEWSTDMTL_XRAY_ESHADER_CHUNK 0x5200
3023 #define NEWSTDMTL_XRAY_CSHADER_CHUNK 0x5201
3024 #define NEWSTDMTL_XRAY_GAMEMTL_CHUNK 0x5202
3025
3026 //#define NEWSTDMTL_BUMP1_CHUNK 0x5200
3027 #define NEWSTDMTL_VERS_CHUNK 0x5300
3028 #define NEWSTDMTL_DIM_REFLECT 0x5400
3029
3030 #define NEWSTDMTL_SELFILLUM_CLR_ON 0x5500
3031 #define NEWSTDMTL_SAMPLING_ON 0x5510
3032 #define NEWSTDMTL_SAMPLING_QUALITY 0x5511
3033
3034 // IO
Save(ISave * isave)3035 IOResult XRayMtl::Save(ISave *isave)
3036 {
3037 ULONG nb;
3038 IOResult res;
3039 isave->BeginChunk(MTL_HDR_CHUNK);
3040 res = MtlBase::Save(isave);
3041 if (res!=IO_OK) return res;
3042 isave->EndChunk();
3043
3044 isave->BeginChunk(NEWSTDMTL_VERS_CHUNK);
3045 int version = CURRENT_NEWSTDMTL_VERSION;
3046 isave->Write(&version, sizeof(version), &nb);
3047 isave->EndChunk();
3048
3049 // xray params
3050 isave->BeginChunk(NEWSTDMTL_XRAY_ESHADER_CHUNK);
3051 isave->WriteCString(GetEShader(eshaderId));
3052 isave->EndChunk();
3053
3054 isave->BeginChunk(NEWSTDMTL_XRAY_CSHADER_CHUNK);
3055 isave->WriteCString(GetCShader(cshaderId));
3056 isave->EndChunk();
3057
3058 isave->BeginChunk(NEWSTDMTL_XRAY_GAMEMTL_CHUNK);
3059 isave->WriteCString(GetGameMtl(gamemtlId));
3060 isave->EndChunk();
3061
3062 return IO_OK;
3063 }
3064
3065
FindNodeRef(ReferenceTarget * rt)3066 static INode* FindNodeRef(ReferenceTarget *rt) {
3067 DependentIterator di(rt);
3068 ReferenceMaker *rm;
3069 INode *nd = NULL;
3070 while (rm=di.Next()) {
3071 if (rm->SuperClassID()==BASENODE_CLASS_ID) return (INode *)rm;
3072 nd = FindNodeRef((ReferenceTarget *)rm);
3073 if (nd) return nd;
3074 }
3075 return NULL;
3076 }
3077
3078
3079
GetNodeScaling(Mtl * m)3080 static float GetNodeScaling(Mtl *m) {
3081 INode *n = FindNodeRef(m);
3082 if (n==NULL)
3083 return 1.0f;
3084 Interval v;
3085 Matrix3 tm = n->GetNodeTM(0, &v);
3086 float f = float( abs(Length(tm.GetRow(0))) + abs(Length(tm.GetRow(1))) + abs(Length(tm.GetRow(2))) )/3.0f;
3087 return f;
3088 }
3089
3090
3091 //-----------------------------------------------------------------------
3092 // DS - 4/7/97: Changed Opacity, Self-illumination, SHininess, Shininess strengh
3093 // so that the map amount blends between the corresponding slider
3094 // setting and the map value. This code fixes up old files so they
3095 // will render the same way. This does not correctly handle animated values
3096 // for the amount or parameter sliders.
3097 //
3098 // KE - 8/4/98 modified for converting old stdmtls to stdmtl2's
3099 // JBW - 11/19/98 updated to convert old stdmtls and v.10 stdmtl2's to ParamBlock2-based XRayMtl's
3100 //-----------------------------------------------------------------------
3101
OldVerFix(int loadVer)3102 void XRayMtl::OldVerFix(int loadVer)
3103 {
3104 ULONG stdParams;
3105
3106 macroRecorder->Disable();
3107
3108 // ask the ClassDesc to make the P_AUTO_CONSTRUCT paramblock2s
3109 stdmtl2CD.MakeAutoParamBlocks(this);
3110
3111 if (loadVer < 10) {
3112 // create a shader, note: always a stdshader as it's an old version
3113 if ( shaderId < 0 || shaderId > 3 ) shaderId = 1; // v1 files
3114 long cid;
3115 switch( shaderId ) {
3116 case 0: cid = PHONGClassID;
3117 pb_shader->SetValue(std2_faceted,0,TRUE);
3118 break;
3119 case 1: cid = PHONGClassID; break;
3120 case 2: cid = METALClassID; break;
3121 case 3: cid = BLINNClassID; break;
3122 }
3123 long indx = FindShader( Class_ID(cid, 0) );
3124
3125 if ( indx < 0 ) return;
3126
3127 // this sets the new shader via pb2 accessor
3128 SetShaderIndx( indx );
3129
3130 pShader->SetSelfIllumClrOn( FALSE );
3131 stdParams = pShader->SupportStdParams();
3132
3133 // convert param blocks
3134 IParamBlock* oldPB = old_pblock;
3135 IParamBlock* newParamBlk = UpdateParameterBlock(stdmtlPB, NPARAMS_O, oldPB,
3136 stdmtl2PB, NPARAMS, NEWSTDMTL_PBVERSION);
3137
3138 // if shader is PB2-based, give it the PB2 remapping descriptor
3139 if (pShader->NumParamBlocks() > 0)
3140 pShader->ConvertParamBlk(stdmtlPB2, NPARAMS_O, oldPB);
3141 else
3142 pShader->ConvertParamBlk(stdmtlPB, NPARAMS_O, oldPB);
3143
3144 ReplaceReference( OLD_PBLOCK_REF, newParamBlk );
3145 UpdateTexmaps();
3146 std2_extended_blk.SetSubTexNo(std2_ep_filter_map, stdIDToChannel[ID_FI]);
3147
3148 SetSamplerIndx( FindSampler( Class_ID(DEFAULT_SAMPLER_CLASS_ID,0) ) );
3149 if (flags & NEWSTDMTL_SSAMP_ON) {
3150 pb_sampling->SetValue( std2_ssampler_enable,0, TRUE );
3151 }
3152
3153 // gloss & strength are swapped from old versions
3154 TexmapSlot tmSlot = maps->txmap[ID_SH];
3155 maps->txmap[ID_SH] = maps->txmap[ID_SS];
3156 maps->txmap[ID_SS] = tmSlot;
3157
3158
3159 }
3160
3161 // now set values that were previously stored outside the PB, prior to update
3162 pb_shader->SetValue(std2_wire, 0, GetFlag(NEWSTDMTL_WIRE)!=0);
3163 pb_shader->SetValue(std2_two_sided, 0, GetFlag(NEWSTDMTL_2SIDE)!=0);
3164 pb_shader->SetValue(std2_face_map, 0, GetFlag(NEWSTDMTL_FACEMAP)!=0);
3165 pb_shader->SetValue(std2_faceted, 0, GetFlag(NEWSTDMTL_FACETED)!=0);
3166
3167 pb_extended->SetValue(std2_opacity_type, 0, (GetFlag(NEWSTDMTL_ADD_TRANSP) ? 2 : GetFlag(NEWSTDMTL_FILT_TRANSP) ? 0 : 1));
3168 pb_extended->SetValue(std2_falloff_type, 0, GetFlag(NEWSTDMTL_FALLOFF_OUT) ? 1 : 0);
3169 pb_extended->SetValue(std2_wire_units, 0, GetFlag(NEWSTDMTL_WIRE_UNITS) ? 1 : 0);
3170 pb_extended->SetValue(std2_apply_refl_dimming, 0, dimReflect);
3171
3172 pShader->SetLockAD( GetFlag(NEWSTDMTL_LOCK_AD)?TRUE:FALSE );
3173 pShader->SetLockDS( GetFlag(NEWSTDMTL_LOCK_DS)?TRUE:FALSE );
3174 pShader->SetLockADTex( GetFlag(NEWSTDMTL_LOCK_ADTEX)!=0 );
3175 pb_maps->SetValue(std2_mp_ad_texlock, 0, GetFlag(NEWSTDMTL_LOCK_ADTEX)!=0 );
3176
3177 if (loadVer < 8) {
3178 Interval v;
3179 Update(0, v);
3180 // In old versions, the ID's & the channel numbers correspond
3181 if (MAPACTIVE(ID_OP)) {
3182 if (maps->txmap[ID_OP].amount != 1.0f)
3183 SetOpacity(0.0f, 0);
3184 }
3185
3186 if ( stdParams & STD_PARAM_SELFILLUM )
3187 if (MAPACTIVE(ID_SI)) {
3188 if (maps->txmap[ID_SI].amount != 1.0f)
3189 pShader->SetSelfIllum(0.0f, 0);
3190 }
3191
3192 if ( stdParams & STD_PARAM_SPECULAR_LEV )
3193 if (MAPACTIVE(ID_SS)) {
3194 float amt = maps->txmap[ID_SS].amount;
3195 SetTexmapAmt(ID_SS, amt * pShader->GetSpecularLevel(0, 0), 0);
3196 pShader->SetSpecularLevel(0.0f, 0);
3197 }
3198
3199 if ( stdParams & STD_PARAM_GLOSSINESS )
3200 if (MAPACTIVE(ID_SH)) {
3201 float amt = maps->txmap[ID_SH].amount;
3202 SetTexmapAmt(ID_SH, amt* pShader->GetGlossiness(0, 0), 0);
3203 pShader->SetGlossiness(0.0f, 0);
3204 }
3205
3206 }
3207 if (loadVer < 9) {
3208 if ( stdParams & STD_PARAM_SOFTEN_LEV )
3209 if (flags&NEWSTDMTL_SOFTEN)
3210 pShader->SetSoftenLevel(.6f, 0);
3211 else
3212 pShader->SetSoftenLevel(0.0f, 0);
3213 }
3214
3215 // at this point we have a v10 Stdmtl2, convert to PB2-based
3216 // distribute old pblock values to new pb2 blocks
3217 UpdateParameterBlock2(extVer10, NPARAMS, old_pblock, &std2_extended_blk, pb_extended);
3218 #ifndef DESIGN_VER
3219 UpdateParameterBlock2(dynVer10, NPARAMS, old_pblock, &std2_dynamics_blk, pb_dynamics);
3220 #endif
3221
3222 // mask off rollup flags
3223 flags &= ~NEWSTDMTL_ROLLUP_FLAGS;
3224 flags |= NEWSTDMTL_ROLLUP1_OPEN;
3225 // pb_shader->SetRolloutOpen( flags & NEWSTDMTL_ROLLUP1_OPEN );
3226
3227 macroRecorder->Enable();
3228
3229 // delete old pblock
3230 ReplaceReference(OLD_PBLOCK_REF, NULL);
3231
3232 }
3233
3234
3235 // versin update post-load call back
3236 class NewStdMtl2UpdateCB: public PostLoadCallback {
3237 public:
3238 // create shader & new pblock
3239 XRayMtl *m;
3240 int loadVersion;
3241
NewStdMtl2UpdateCB(XRayMtl * s,int loadVers)3242 NewStdMtl2UpdateCB( XRayMtl *s, int loadVers ){ m = s; loadVersion = loadVers; }
proc(ILoad * iload)3243 void proc(ILoad *iload) {
3244 m->OldVerFix( loadVersion );
3245 delete this;
3246 }
3247 };
3248
BumpFix()3249 void XRayMtl::BumpFix( ) {
3250 // Fix up bump map amount on old files if the node is scaled. DS 4/16/99
3251 int bumpChannel = stdIDToChannel[ID_BU];
3252 if ((*maps)[ bumpChannel].IsActive()) {
3253 float s = GetNodeScaling(this);
3254 if (s!=1.0f) {
3255 float am = GetTexmapAmt(bumpChannel);
3256 SetTexmapAmt(bumpChannel, s*am, 0);
3257 }
3258 }
3259 }
3260
3261
3262 // Bumpp map amount fix post-load call back
3263 class NewStdMtl2BumpFixCB: public PostLoadCallback {
3264 public:
3265 // create shader & new pblock
3266 XRayMtl *m;
3267
NewStdMtl2BumpFixCB(XRayMtl * s)3268 NewStdMtl2BumpFixCB( XRayMtl *s ){ m = s; }
Priority()3269 int Priority() { return 7; } // run at lower priority after normal PLCB's are all finished
proc(ILoad * iload)3270 void proc(ILoad *iload) {
3271 m->BumpFix( );
3272 delete this;
3273 }
3274 };
3275
3276 // post-load finalize callback
3277 class NewStdMtl2CB: public PostLoadCallback {
3278 public:
3279 XRayMtl *m;
3280
NewStdMtl2CB(XRayMtl * s)3281 NewStdMtl2CB(XRayMtl *s){ m = s; }
proc(ILoad * iload)3282 void proc(ILoad *iload)
3283 {
3284 // ensure all map-related parameters are set up
3285 m->UpdateTexmaps();
3286
3287 // make sure the right indx is selected for shaders & samplers
3288 m->SetShaderIndx( m->FindShader( m->pShader->ClassID() ), FALSE );
3289 if( m->pixelSampler == NULL ) // for some alpha files!
3290 m->SetSamplerIndx( m->FindSampler( Class_ID(DEFAULT_SAMPLER_CLASS_ID,0) ) );
3291
3292 m->SetSamplerIndx( m->FindSampler( m->pixelSampler->ClassID() ), FALSE );
3293 m->SetFlag(NEWSTDMTL_SSAMP_ON, m->pixelSampler->GetEnable() );
3294
3295 #ifndef DESIGN_VER
3296 if( m->pb_dynamics == NULL )
3297 //create the parameter block
3298 CreateParameterBlock2(&std2_dynamics_blk, m);
3299 #endif
3300 if( m->pb_xray == NULL )
3301 //create the parameter block
3302 CreateParameterBlock2(&std2_xray_blk, m);
3303
3304 m->SetEShaderIndx( m->eshaderId );
3305 m->SetCShaderIndx( m->cshaderId );
3306 m->SetGameMtlIndx( m->gamemtlId );
3307
3308
3309 // DS - 2/11/99 This Update should not be here: it causes all
3310 // submaps to be loaded when loading, which makes loading matlibs very slow.
3311 // Interval i;
3312 // i.SetInfinite();
3313 // m->Update(0, i);
3314
3315 delete this;
3316 }
3317 };
3318
Load(ILoad * iload)3319 IOResult XRayMtl::Load(ILoad *iload) {
3320 ULONG nb;
3321 int id;
3322 int version = 0;
3323 dimReflect = FALSE;
3324
3325 // fix old ver
3326 gamemtlId = -1;
3327
3328 IOResult res;
3329 while (IO_OK==(res=iload->OpenChunk())) {
3330 switch(id = iload->CurChunkID()) {
3331 case MTL_HDR_CHUNK:
3332 res = MtlBase::Load(iload);
3333 ivalid.SetEmpty();
3334 break;
3335 case NEWSTDMTL_FLAGS_CHUNK:
3336 res = iload->Read(&flags, sizeof(flags), &nb);
3337 break;
3338 case NEWSTDMTL_SHADING_CHUNK:
3339 res = iload->Read(&shaderId, sizeof(shaderId), &nb);
3340 break;
3341 case NEWSTDMTL_XRAY_ESHADER_CHUNK:{
3342 LPSTR es_name;
3343 res = iload->ReadCStringChunk(&es_name);
3344 if (res==IO_OK) eshaderId = XRayMtl::FindEShader(es_name);
3345 }break;
3346 case NEWSTDMTL_XRAY_CSHADER_CHUNK:{
3347 LPSTR cs_name;
3348 res = iload->ReadCStringChunk(&cs_name);
3349 if (res==IO_OK) cshaderId = XRayMtl::FindCShader(cs_name);
3350 }break;
3351 case NEWSTDMTL_XRAY_GAMEMTL_CHUNK:{
3352 LPSTR gm_name;
3353 res = iload->ReadCStringChunk(&gm_name);
3354 if (res==IO_OK) gamemtlId = XRayMtl::FindGameMtl(gm_name);
3355 }break;
3356 case NEWSTDMTL_VERS_CHUNK:
3357 res = iload->Read(&version, sizeof(version), &nb);
3358 break;
3359 case NEWSTDMTL_TEX_ONOFF_CHUNK:
3360 {
3361 ULONG f;
3362 res = iload->Read(&f, sizeof(f), &nb);
3363 for (int i=0; i<STD2_NMAX_TEXMAPS; i++)
3364 maps->txmap[i].mapOn = (f&(1<<i))?1:0;
3365 }
3366 break;
3367 case NEWSTDMTL_DIM_REFLECT:
3368 dimReflect = TRUE;
3369 break;
3370 }
3371 iload->CloseChunk();
3372 if (res!=IO_OK)
3373 return res;
3374 }
3375
3376 // register version updaters
3377 if (version <= FINAL_PARAMBLOCK_v1_VERSION) {
3378 iload->RegisterPostLoadCallback(new ParamBlockPLCB((ParamVersionDesc*)oldNewStdMtlVersions, NEWSTDMTL_NUMOLDVER, &stdMtlVersion, this, 0));
3379 iload->RegisterPostLoadCallback(new NewStdMtl2UpdateCB(this, version));
3380 if (version<12)
3381 iload->RegisterPostLoadCallback(new NewStdMtl2BumpFixCB(this));
3382 iload->SetObsolete();
3383 }
3384
3385 if (TextureDisplayEnabled()) {
3386 IncrActive();
3387 }
3388
3389 if (gamemtlId==-1) gamemtlId = XRayMtl::FindGameMtl("default");
3390
3391 // register plcb to finalize setup
3392 iload->RegisterPostLoadCallback(new NewStdMtl2CB(this));
3393
3394 return IO_OK;
3395 }
3396
3397
3398 #define TRANSP_SUB 0
3399 #define TRANSP_ADD 1
3400 #define TRANSP_FILTER 2
3401
3402
3403 // Composite c_over on top of c. Assume c_over has pre-multiplied alpha.
AlphaCompCol(Color & c,RGBA c_over)3404 IC void AlphaCompCol(Color& c, RGBA c_over) {
3405 float ia = 1.0f - abs(c_over.a);
3406 ia = LBound( ia );
3407 c.r = c.r * ia + c_over.r;
3408 c.g = c.g * ia + c_over.g;
3409 c.b = c.b * ia + c_over.b;
3410 }
3411
3412 //////////////////////////////////////////////////////////////////////////////
3413 //
3414 // transpColor utility, same as in shaders/shaderUtil
3415 //
TranspColor(float opac,Color filt,Color diff)3416 Color XRayMtl::TranspColor( float opac, Color filt, Color diff )
3417 {
3418 // Compute the color of the transparent filter color
3419 if (flags & NEWSTDMTL_ADD_TRANSP) {
3420 float f = 1.0f - opac;
3421 return Color(f, f, f);
3422
3423 } else if ( flags & NEWSTDMTL_FILT_TRANSP ){
3424 // Transparent Filter color mapping
3425 if (opac>0.5f) {
3426 // darken as opac goes ( 0.5--> 1.0)
3427 // so that max component reaches 0.0f when opac reaches 1.0
3428 // find max component of filt
3429 float m = Max(filt);
3430 float d = 2.0f*(opac-.5f)*m;
3431 Color fc = filt-d;
3432 fc = LBound( fc );
3433 return fc;
3434 } else {
3435 // lighten as opac goes ( 0.5--> 0.0)
3436 // so that min component reaches 1.0f when opac reaches 1.0
3437 // find min component of filt
3438 float m = Min(filt);
3439 float d = (1.0f-2.0f*opac)*(1.0f-m);
3440 Color fc = filt+d;
3441 fc = UBound( fc );
3442 return fc;
3443 }
3444
3445 } else {
3446 // original 3DS transparency, subtractive using diff color
3447 Color f = (1.0f-diff);
3448 return (1.0f-opac)*f;
3449 }
3450 }
3451
3452
3453 #define DOMAP(n) ((n>=0) && sc.doMaps&&(*maps)[ n ].IsActive())
3454
3455 #ifdef _DEBUG
3456 static long xStop = -1;
3457 static long yStop = -1;
3458 #endif
3459
3460 // begin - ke/mjm - 03.16.00 - merge reshading code
3461 //BOOL XRayMtl::SupportsReShading(ShadeContext& sc) { return TRUE; }
3462
PreShade(ShadeContext & sc,IReshadeFragment * pFrag)3463 void XRayMtl::PreShade(ShadeContext& sc, IReshadeFragment* pFrag )
3464 {
3465 RGBA mval;
3466 Point3 N, N0, P;
3467
3468 #ifdef _DEBUG
3469 IPoint2 sPt = sc.ScreenCoord();
3470 if( sPt.x == xStop && sPt.y == yStop )
3471 long junk = -1;
3472 #endif
3473
3474 BOOL bumped = FALSE;
3475 N = sc.Normal();
3476
3477 int ambChan = stdIDToChannel[ ID_AM ];
3478 int diffChan = stdIDToChannel[ ID_DI ];
3479 int trChan = stdIDToChannel[ ID_OP ];
3480 int filtChan = stdIDToChannel[ ID_FI ];
3481 ULONG trType = (flags & NEWSTDMTL_FILT_TRANSP) ? TRANSP_FILTER :
3482 (flags & NEWSTDMTL_ADD_TRANSP) ? TRANSP_ADD : TRANSP_SUB;
3483
3484
3485 // Do texture mapping
3486 sc.SetIOR(ioRefract);
3487
3488 // Bump mapping: Do this FIRST so other maps can use the perturbed normal
3489 int bumpChannel = stdIDToChannel[ID_BU];
3490 if (DOMAP(bumpChannel)) {
3491 Point3 dn = (*maps)[bumpChannel].EvalNormalPerturb(sc);
3492 bumped = TRUE;
3493 N = Normalize( N + (sc.backFace?-dn:dn));
3494 // NB: shadeContext has perturbed normal
3495 sc.SetNormal(N);
3496 pFrag->AddUnitVecChannel( N );
3497 }
3498
3499 // All normal color & scalar maps are handled here
3500 long t0 = pShader->ChannelType(0);
3501 RGBA c;
3502 for ( long i = 0; i < STD2_NMAX_TEXMAPS; ++i ) {
3503 if ( sc.doMaps && (*maps)[ i ].IsActive()) {
3504 long t = pShader->ChannelType(i);
3505 // composite the channel
3506 if ( (t & SKIP_CHANNELS)==0 ){
3507 if ( t & MONO_CHANNEL ) {
3508 // note: r always holds channel data for mono channels
3509 float m = (*maps)[i].map->EvalMono(sc);
3510 pFrag->AddFloatChannel( m );
3511 } else {
3512 if ( i != ambChan || (flags & NEWSTDMTL_LOCK_ADTEX)==0 ) {
3513 c = (*maps)[i].map->EvalColor(sc);
3514 if ((*maps)[i].map->IsHighDynamicRange()) {
3515 LogLUV32Pixel lc;
3516
3517 lc = c;
3518 pFrag->AddIntChannel(lc.value);
3519 pFrag->AddFloatChannel(c.a);
3520 }
3521 else {
3522 BoundInPlace( c );
3523 pFrag->AddColorChannel(c);
3524 }
3525 }
3526 }
3527 }
3528 }
3529 }
3530
3531 // Evaluate reflection map.
3532 int reflChan = stdIDToChannel[ ID_RL ];
3533 if (DOMAP(reflChan)) {
3534 AColor rcol;
3535 Texmap *reflmap = (*maps)[reflChan].map;
3536 if (reflmap->HandleOwnViewPerturb()) {
3537 sc.TossCache(reflmap);
3538 rcol = reflmap->EvalColor(sc);
3539 } else
3540 rcol = sc.EvalEnvironMap(reflmap, sc.ReflectVector());
3541
3542 if ((*maps)[reflChan].map->IsHighDynamicRange()) {
3543 LogLUV32Pixel lc;
3544
3545 lc = rcol;
3546 pFrag->AddIntChannel(lc.value);
3547 pFrag->AddFloatChannel(rcol.a);
3548 }
3549 else {
3550 pFrag->AddColorChannel(rcol);
3551 }
3552 }
3553
3554 // do refraction map
3555 int refrChan = stdIDToChannel[ ID_RR ];
3556 if (DOMAP(refrChan)) {
3557 // Evaluate refraction map, as yet unfiltered by filter color.
3558 Texmap *refrmap = (*maps)[refrChan].map;
3559 AColor rcol;
3560 if (refrmap->HandleOwnViewPerturb())
3561 rcol = refrmap->EvalColor( sc );
3562 else
3563 rcol = sc.EvalEnvironMap( refrmap, sc.RefractVector(ioRefract) );
3564
3565 if ((*maps)[refrChan].map->IsHighDynamicRange()) {
3566 LogLUV32Pixel lc;
3567
3568 lc = rcol;
3569 pFrag->AddIntChannel(lc.value);
3570 }
3571 else {
3572 pFrag->AddColorChannel(rcol);
3573 }
3574 }
3575
3576 // see if the shader wants to save anything
3577 IReshading* pReshading;
3578 if((pReshading = (IReshading*)pShader->GetInterface(IID_IReshading)) != NULL ){
3579 pReshading->PreShade( sc, pFrag );
3580 }
3581 if( bumped )
3582 sc.SetNormal( sc.OrigNormal() );
3583 }
3584
PostShade(ShadeContext & sc,IReshadeFragment * pFrag,int & nextTexIndex,IllumParams *)3585 void XRayMtl::PostShade(ShadeContext& sc, IReshadeFragment* pFrag, int& nextTexIndex, IllumParams*)
3586 {
3587 IllumParams ip(0, NULL);
3588 Color lightCol, rescol, diffIllum0;
3589 float opac;
3590 RGBA mval;
3591 Point3 P;
3592 BOOL bumped = FALSE;
3593
3594 #ifdef _DEBUG
3595 IPoint2 sPt = sc.ScreenCoord();
3596 if( sPt.x == xStop && sPt.y == yStop )
3597 long junk = -1;
3598 #endif
3599
3600 pShader->Update( sc.CurTime(), FOREVER ); // mjm - 12.17.99
3601 pShader->GetIllumParams( sc, ip );
3602 ip.ClearOutputs();
3603 ip.pShader = pShader;
3604 ip.pMtl = this;
3605
3606 opac = opacity;
3607
3608 int ambChan = stdIDToChannel[ ID_AM ];
3609 int diffChan = stdIDToChannel[ ID_DI ];
3610 int trChan = stdIDToChannel[ ID_OP ];
3611 int filtChan = stdIDToChannel[ ID_FI ];
3612 int reflChan = stdIDToChannel[ ID_RL ];
3613 int refrChan = stdIDToChannel[ ID_RR ];
3614
3615 if ( filtChan >= 0 )ip.channels[filtChan] = filter;
3616 if ( trChan >= 0 ) ip.channels[trChan].r = opac;
3617 ULONG trType = (flags & NEWSTDMTL_FILT_TRANSP) ? TRANSP_FILTER :
3618 (flags & NEWSTDMTL_ADD_TRANSP) ? TRANSP_ADD : TRANSP_SUB;
3619
3620 P = sc.P(); // position
3621
3622 ip.stdParams = pShader->SupportStdParams();
3623
3624 // Do texture mapping
3625 ip.hasComponents = 0;
3626 ip.stdIDToChannel = stdIDToChannel;
3627 // sc.SetIOR(ioRefract);
3628
3629 // All normal color & scalar maps are handled here
3630 if (pFrag->NChannels() > 0) {
3631
3632 // bump mapping
3633 if( DOMAP( stdIDToChannel[ ID_BU ] ) ) {
3634 bumped = TRUE;
3635 // NB: shadeContext has perturbed normal
3636 sc.SetNormal( pFrag->GetUnitVecChannel( nextTexIndex++ ) );
3637 }
3638
3639 RGBA c;
3640 for ( long i = 0; i < STD2_NMAX_TEXMAPS; ++i ) {
3641 if ( sc.doMaps && (*maps)[ i ].IsActive()) {
3642 long t = pShader->ChannelType(i);
3643 // composite the channel
3644 if ( (t & SKIP_CHANNELS)==0 ){
3645 if ( t & MONO_CHANNEL ) {
3646 // note: r always holds channel data for mono channels
3647 ip.channels[ i ].r = (*maps)[i].LerpMono( ip.channels[ i ].r, pFrag->GetFloatChannel(nextTexIndex++)); // mjm - 1.17.00
3648 } else {
3649 if ( i != ambChan || (flags & NEWSTDMTL_LOCK_ADTEX)==0 ) {
3650 if ((*maps)[ i ].map->IsHighDynamicRange()) {
3651 LogLUV32Pixel lc;
3652 lc.value = pFrag->GetIntChannel(nextTexIndex++);
3653 lc.GetRGB(c);
3654 c.a = pFrag->GetFloatChannel(nextTexIndex++);
3655 }
3656 else {
3657 c = pFrag->GetColorChannel(nextTexIndex++);
3658 }
3659 c *= (*maps)[i].amount; // mjm - 1.17.00
3660 AlphaCompCol( ip.channels[ i ], c);
3661 }
3662 }
3663 // lock adtex, really channels 0 & 1
3664 if ( i == diffChan && (flags & NEWSTDMTL_LOCK_ADTEX) && ambChan >= 0 ) {
3665 AlphaCompCol( ip.channels[ ambChan ], c );
3666 }
3667 }// end, don't skip
3668 } // end, is active
3669 }// end, for each possible map
3670
3671 // Evaluate reflection map.
3672 if ( (*maps)[ reflChan ].map )
3673 ip.hasComponents |= HAS_REFLECT_MAP;
3674
3675 if (DOMAP(reflChan) ) {
3676 ip.hasComponents |= HAS_REFLECT;
3677 AColor rcol; // mjm - 1.17.00
3678 if ((*maps)[ reflChan ].map->IsHighDynamicRange()) {
3679 LogLUV32Pixel lc;
3680 lc.value = pFrag->GetIntChannel(nextTexIndex++);
3681 lc.GetRGB(rcol);
3682 rcol.a = pFrag->GetFloatChannel(nextTexIndex++);
3683 }
3684 else {
3685 rcol = pFrag->GetColorChannel( nextTexIndex++ ); // mjm - 1.17.00
3686 }
3687 Color rc(rcol.r, rcol.g, rcol.b);
3688 ip.channels[reflChan] = rc;
3689 ip.reflectAmt = rcol.a * (*maps)[reflChan].amount;
3690 }
3691
3692 // do refraction map
3693 if ( (*maps)[ refrChan ].map )
3694 ip.hasComponents |= HAS_REFRACT_MAP;
3695
3696 if (DOMAP(refrChan) ) {
3697 // Evaluate refraction map, as yet unfiltered by filter color.
3698 ip.refractAmt = (*maps)[refrChan].amount;
3699 AColor rcol; // mjm - 1.17.00
3700 if ((*maps)[ refrChan ].map->IsHighDynamicRange()) {
3701 LogLUV32Pixel lc;
3702 lc.value = pFrag->GetIntChannel(nextTexIndex++);
3703 lc.GetRGB(rcol);
3704 }
3705 else {
3706 rcol = pFrag->GetColorChannel( nextTexIndex++ ); // mjm - 1.17.00
3707 }
3708 Color rc( rcol.r, rcol.g, rcol.b );
3709 ip.channels[refrChan] = rc;
3710 ip.hasComponents |= HAS_REFRACT;
3711 }
3712 } // end, at least one map
3713
3714 // get falloff opacity for possible use by shader or compositor
3715 opac = ip.channels[trChan].r; // get (perhaps) textured opacity
3716
3717 ip.finalOpac = GetEffOpacity( sc, opac );
3718 if( ip.finalOpac < 1.0f )
3719 ip.hasComponents |= HAS_OPACITY;
3720
3721 // init the global ambient
3722 ip.ambIllumOut = sc.ambientLight;
3723
3724 // mapping done, illuminate...
3725 IReshading* pReshading;
3726 if((pReshading = (IReshading*)pShader->GetInterface(IID_IReshading)) != NULL ){
3727 pReshading->PostShade( sc, pFrag, nextTexIndex, &ip );
3728 }
3729
3730 // return color in sc, not the frag itself
3731 sc.out.c = ip.finalC;
3732 sc.out.t = ip.finalT;
3733
3734 if( bumped )
3735 sc.SetNormal( sc.OrigNormal() );
3736 }
3737
3738 // too late for sdk, eco in progress
CloneIp(IllumParams & ip)3739 IllumParams* CloneIp( IllumParams& ip )
3740 {
3741 IllumParams* pClone = new IllumParams( ip.nUserIllumOut, ip.userIllumNames );
3742 pClone->finalC = ip.finalC;
3743 pClone->finalT = ip.finalT;
3744 pClone->finalOpac = ip.finalOpac;
3745 pClone->finalAttenuation = ip.finalAttenuation;
3746 pClone->ambIllumOut = ip.ambIllumOut;
3747 pClone->diffIllumOut = ip.diffIllumOut;
3748 pClone->transIllumOut = ip.transIllumOut;
3749 pClone->selfIllumOut = ip.selfIllumOut;
3750 pClone->specIllumOut = ip.specIllumOut;
3751 pClone->reflIllumOut = ip.reflIllumOut;
3752 pClone->transIllumOut = ip.transIllumOut;
3753 pClone->diffIllumIntens = ip.diffIllumIntens;
3754 for( int i=0; i < ip.nUserIllumOut; ++i )
3755 pClone->userIllumOut[i] = ip.userIllumOut[i];
3756
3757 pClone->stdParams = ip.stdParams;
3758 pClone->hasComponents = ip.hasComponents;
3759 pClone->pShader = ip.pShader;
3760 pClone->pMtl = ip.pMtl;
3761 pClone->stdIDToChannel = ip.stdIDToChannel;
3762 pClone->refractAmt = ip.refractAmt;
3763 pClone->reflectAmt = ip.reflectAmt;
3764
3765 for( i=0; i < STD2_NMAX_TEXMAPS; ++i )
3766 pClone->channels[ i ] = ip.channels[ i ];
3767
3768 return pClone;
3769 }
3770
3771
3772 // if this function changes, please also check SupportsReShading, PreShade, PostShade
3773 // end - ke/mjm - 03.16.00 - merge reshading code
3774 // [attilas|24.5.2000] if this function changes, please also check EvalColorStdChannel
Shade(ShadeContext & sc)3775 void XRayMtl::Shade(ShadeContext& sc)
3776 {
3777 IllumParams ip( pShader->nUserIllumOut(), pShader->UserIllumNameArray() );
3778 Color lightCol, rescol, diffIllum0;
3779 float opac;
3780 RGBA mval;
3781 Point3 N0, P;
3782
3783 #ifdef _DEBUG
3784 IPoint2 sPt = sc.ScreenCoord();
3785 if( sPt.x == xStop && sPt.y == yStop )
3786 long junk = -1;
3787 #endif
3788
3789 BOOL bumped = FALSE;
3790 if (gbufID) sc.SetGBufferID(gbufID);
3791 // ip.mtlFlags = flags;
3792
3793 pShader->GetIllumParams( sc, ip );
3794 ip.ClearOutputs();
3795 ip.pShader = pShader;
3796 ip.pMtl = this;
3797
3798 // N0 = ip.N = sc.Normal();
3799 N0 = sc.Normal();
3800 opac = opacity;
3801
3802 int ambChan = stdIDToChannel[ ID_AM ];
3803 int diffChan = stdIDToChannel[ ID_DI ];
3804 int trChan = stdIDToChannel[ ID_OP ];
3805 int filtChan = stdIDToChannel[ ID_FI ];
3806 if ( filtChan >= 0 )ip.channels[filtChan] = filter;
3807 if ( trChan >= 0 ) ip.channels[trChan].r = opac;
3808 ULONG trType = (flags & NEWSTDMTL_FILT_TRANSP) ? TRANSP_FILTER :
3809 (flags & NEWSTDMTL_ADD_TRANSP) ? TRANSP_ADD : TRANSP_SUB;
3810
3811 if (sc.mode==SCMODE_SHADOW) {
3812 // Opacity mapping;
3813 if (DOMAP(trChan))
3814 opac = (*maps)[trChan].LerpEvalMono(sc, opac);
3815
3816 // "Shadow mode": This just computes the transparency, which is all
3817 // you need for shadowing.
3818 if (opac!=1.0f || opfall!=0.0f) {
3819
3820 if (opfall != 0.0f) {
3821 opac = GetEffOpacity(sc, opac);
3822 }
3823
3824 // Transparency may use diffuse color mapping, check for orig 3ds transp
3825 if ((flags & (NEWSTDMTL_ADD_TRANSP|NEWSTDMTL_FILT_TRANSP))==0) {
3826 if (DOMAP(diffChan)) {
3827 mval = (*maps)[diffChan].Eval(sc);
3828 AlphaCompCol(ip.channels[diffChan], mval);
3829 }
3830 }
3831 // Transparency may also use filter color mapping
3832 if ( flags & NEWSTDMTL_FILT_TRANSP ){
3833 if (DOMAP(filtChan)) {
3834 mval = (*maps)[filtChan].Eval(sc);
3835 AlphaCompCol(ip.channels[filtChan], mval);
3836 }
3837 }
3838 // Compute the transpareny color
3839 sc.out.t = TranspColor( opac, ip.channels[filtChan], ip.channels[diffChan]);
3840 } else
3841 sc.out.t.Black();
3842 return;
3843 } // end, shadow mode
3844
3845 // any shader can be faceted...& bumpmapped as well
3846 if ( flags & NEWSTDMTL_FACETED ){
3847 Point3 N = sc.GNormal();
3848 bumped = TRUE;
3849 sc.SetNormal(N);
3850 }
3851
3852 P = sc.P(); // position
3853
3854 ip.stdParams = pShader->SupportStdParams();
3855
3856 // Do texture mapping
3857 ip.hasComponents = 0;
3858 ip.stdIDToChannel = stdIDToChannel;
3859 sc.SetIOR(ioRefract);
3860
3861 // Bump mapping: Do this FIRST so other maps can use the perturbed normal
3862 int bumpChannel = stdIDToChannel[ID_BU];
3863 if (DOMAP(bumpChannel)) {
3864 ip.hasComponents |= HAS_BUMPS;
3865 Point3 dn = (*maps)[bumpChannel].EvalNormalPerturb(sc);
3866 Point3 N = Normalize( sc.Normal() + (sc.backFace?-dn:dn) );
3867 sc.SetNormal(N);
3868 bumped = TRUE;
3869 }
3870
3871 // All normal color & scalar maps are handled here
3872 long t0 = pShader->ChannelType(0);
3873 RGBA c;
3874 for ( long i = 0; i < STD2_NMAX_TEXMAPS; ++i ) {
3875 if ( sc.doMaps && (*maps)[ i ].IsActive()) {
3876 long t = pShader->ChannelType(i);
3877 // composite the channel
3878 if ( (t & SKIP_CHANNELS)==0 ){
3879 if ( t & MONO_CHANNEL ) {
3880 // note: x always holds channel data for mono channels
3881 ip.channels[ i ].r = (*maps)[i].LerpEvalMono(sc, ip.channels[ i ].r );
3882 } else {
3883 if ( i != ambChan || (flags & NEWSTDMTL_LOCK_ADTEX)==0 ) {
3884 c = (*maps)[i].Eval(sc);
3885 AlphaCompCol( ip.channels[ i ], c);
3886 }
3887 }
3888 // lock adtex, really channels 0 & 1
3889 if ( i == diffChan && ambChan >= 0 && (flags & NEWSTDMTL_LOCK_ADTEX) ) {
3890 if ( t0 & MONO_CHANNEL ) {
3891 ip.channels[ ambChan ].r = (*maps)[diffChan].LerpEvalMono(sc, ip.channels[diffChan].r );
3892 } else {
3893 AlphaCompCol( ip.channels[ ambChan ], c );
3894 }
3895
3896 }
3897 }
3898 }
3899 }
3900
3901 // Evaluate reflection map.
3902 int reflChan = stdIDToChannel[ ID_RL ];
3903 if ( (*maps)[ reflChan ].map )
3904 ip.hasComponents |= HAS_REFLECT_MAP;
3905
3906 if (DOMAP(reflChan)) {
3907 ip.hasComponents |= HAS_REFLECT;
3908 AColor rcol;
3909 Texmap *reflmap = (*maps)[reflChan].map;
3910 if (reflmap->HandleOwnViewPerturb()) {
3911 sc.TossCache(reflmap);
3912 rcol = reflmap->EvalColor(sc);
3913 } else
3914 rcol = sc.EvalEnvironMap(reflmap, sc.ReflectVector());
3915 Color rc(rcol.r, rcol.g, rcol.b);
3916 ip.channels[reflChan] = rc;
3917 ip.reflectAmt = rcol.a * (*maps)[reflChan].amount;
3918 }
3919
3920 // do refraction map
3921 int refrChan = stdIDToChannel[ ID_RR ];
3922 if ( (*maps)[ reflChan ].map )
3923 ip.hasComponents |= HAS_REFRACT_MAP;
3924
3925 if (DOMAP(refrChan)) {
3926 // Evaluate refraction map, as yet unfiltered by filter color.
3927 ip.refractAmt = (*maps)[refrChan].amount;
3928 Texmap *refrmap = (*maps)[refrChan].map;
3929 AColor rcol;
3930 if (refrmap->HandleOwnViewPerturb())
3931 rcol = refrmap->EvalColor( sc );
3932 else
3933 rcol = sc.EvalEnvironMap( refrmap, sc.RefractVector(ioRefract) );
3934
3935 Color rc( rcol.r, rcol.g, rcol.b );
3936 ip.channels[refrChan] = rc;
3937 ip.hasComponents |= HAS_REFRACT;
3938 }
3939
3940 // get falloff opacity for possible use by shader or compositor
3941 opac = ip.channels[trChan].r; // get (perhaps) textured opacity
3942
3943 ip.finalOpac = GetEffOpacity(sc, opac);
3944 if(ip.finalOpac < 1.0f)
3945 ip.hasComponents |= HAS_OPACITY;
3946
3947 // init the global ambient
3948 ip.ambIllumOut = sc.ambientLight;
3949
3950 // mapping done, illuminate...
3951 pShader->Illum(sc, ip);
3952
3953 // return color in sc, not the frag itself
3954 sc.out.c = ip.finalC;
3955 sc.out.t = ip.finalT;
3956
3957 // Render Elements
3958 // note: shadow must be on for any shadows to work. no ele's will get shadows
3959 // with shadows off
3960 int nEles = sc.NRenderElements();
3961 if( nEles != 0 ){
3962 IllumParams* pIp2 = CloneIp( ip ); // too late for sdk, eco in progress
3963 if( sc.shadow ){
3964 // get unshadowed ip
3965 sc.shadow = FALSE;
3966 pIp2->ClearOutputs();
3967 pShader->Illum(sc, *pIp2);
3968 sc.shadow = TRUE;
3969 }
3970 for( int i=0; i < nEles; ++i ){
3971 IRenderElement* pEle = sc.GetRenderElement(i);
3972 if( pEle->IsEnabled() ){
3973 MaxRenderElement* pMaxEle = (MaxRenderElement*)pEle->GetInterface( MaxRenderElement::IID );
3974 if( pEle->ShadowsApplied() )
3975 pMaxEle->PostIllum( sc, ip );
3976 else
3977 pMaxEle->PostIllum( sc, *pIp2 );
3978 }
3979 }
3980 delete pIp2;
3981 }
3982
3983 if (bumped) sc.SetNormal(N0); // restore normal
3984 }
3985
3986
EvalDisplacement(ShadeContext & sc)3987 float XRayMtl::EvalDisplacement(ShadeContext& sc) {
3988 int dispChan = stdIDToChannel[ ID_DP ];
3989 if (DOMAP(dispChan))
3990 return (*maps)[dispChan].EvalMono(sc);
3991 else return 0.0f;
3992 }
3993
3994
DisplacementValidity(TimeValue t)3995 Interval XRayMtl::DisplacementValidity(TimeValue t) {
3996 int dispChan = stdIDToChannel[ ID_DP ];
3997 if (MAPACTIVE(dispChan)) {
3998 Interval iv;
3999 iv.SetInfinite();
4000 maps->txmap[dispChan].Update(t, iv);
4001 return iv;
4002 }
4003 else
4004 return FOREVER;
4005 }
4006
DiscardTexHandles()4007 void XRayMtl::DiscardTexHandles() {
4008 for (int i=0; i<2; i++) {
4009 if (texHandle[i]) {
4010 texHandle[i]->DeleteThis();
4011 texHandle[i] = NULL;
4012 }
4013 }
4014 texHandleValid.SetEmpty();
4015 }
4016
4017 // begin - dds- 04.27.00 - multiple map display support
ActivateTexDisplay(BOOL onoff)4018 void XRayMtl::ActivateTexDisplay(BOOL onoff) {
4019 if (!onoff) {
4020 DiscardTexHandles();
4021 }
4022 }
4023
4024 struct TextOps {
4025 UBYTE colorOp;
4026 UBYTE colorAlphaSource;
4027 UBYTE colorScale;
4028 UBYTE alphaOp;
4029 UBYTE alphaAlphaSource;
4030 UBYTE alphaScale;
4031 };
4032
4033 // TBD: these values have to be corrected.
4034 #define TXOP_MODULATE 0
4035 #define TXOP_ALPHABLEND 1
4036 #define TXOP_OPACITY 2
4037 static TextOps txops[] = {
4038 { GW_TEX_MODULATE, GW_TEX_TEXTURE, GW_TEX_SCALE_1X, GW_TEX_LEAVE, GW_TEX_TEXTURE, GW_TEX_SCALE_1X },
4039 { GW_TEX_ALPHA_BLEND, GW_TEX_TEXTURE, GW_TEX_SCALE_1X, GW_TEX_LEAVE, GW_TEX_TEXTURE, GW_TEX_SCALE_1X },
4040 { GW_TEX_LEAVE, GW_TEX_TEXTURE, GW_TEX_SCALE_1X, GW_TEX_REPLACE, GW_TEX_TEXTURE, GW_TEX_SCALE_1X },
4041 };
4042
SetTexOps(Material * mtl,int i,int type)4043 void XRayMtl::SetTexOps(Material *mtl, int i, int type) {
4044 TextureInfo *ti = &mtl->texture[i];
4045 ti->colorOp = txops[type].colorOp;
4046 ti->colorAlphaSource = txops[type].colorAlphaSource;
4047 ti->colorScale = txops[type].colorScale;
4048 ti->alphaOp = txops[type].alphaOp;
4049 ti->alphaAlphaSource = txops[type].alphaAlphaSource;
4050 ti->alphaScale = txops[type].alphaScale;
4051 texOpsType[i] = type;
4052 }
4053
4054 #define BMIDATA(x) ((UBYTE *)((BYTE *)(x) + sizeof(BITMAPINFOHEADER)))
4055
StuffAlpha(BITMAPINFO * bi,float amt,float opac,Color fill)4056 static void StuffAlpha(BITMAPINFO *bi, float amt, float opac, Color fill) {
4057 int w = bi->bmiHeader.biWidth;
4058 int h = bi->bmiHeader.biHeight;
4059 int npix = w*h;
4060 UBYTE *a = BMIDATA(bi);
4061 Color24 col;
4062 col.r = (int)(fill.r*255.0f);
4063 col.g = (int)(fill.g*255.0f);
4064 col.b = (int)(fill.b*255.0f);
4065 if (amt<1.0f) {
4066 int ia = int(amt*255.0f);
4067 int ic = int( (1.0f-amt)*opac*255.0f);
4068 for (int j=0; j<npix; j++) {
4069 a[3] = ((( (a[0]+a[1]+a[2])/3 )*ia )>>8) + ic;
4070 a[0] = col.b;
4071 a[1] = col.g;
4072 a[2] = col.r;
4073 a += 4;
4074 }
4075 }
4076 else {
4077 for (int j=0; j<npix; j++) {
4078 a[3] = (a[0]+a[1]+a[2])/3;
4079 a[0] = col.b;
4080 a[1] = col.g;
4081 a[2] = col.r;
4082 a += 4;
4083 }
4084 }
4085 }
4086
4087
StuffAlphaInto(BITMAPINFO * bia,BITMAPINFO * bi,float amt,float opac)4088 static void StuffAlphaInto(BITMAPINFO *bia, BITMAPINFO *bi, float amt, float opac) {
4089 int w = bi->bmiHeader.biWidth;
4090 int h = bi->bmiHeader.biHeight;
4091 int npix = w*h;
4092 UBYTE *a = BMIDATA(bia);
4093 UBYTE *b = BMIDATA(bi);
4094 if (amt<1.0f) {
4095 int ia = int(amt*255.0f);
4096 int ic = int( (1.0f-amt)*opac*255.0f);
4097 for (int j=0; j<npix; j++) {
4098 b[3] = ((( (a[0]+a[1]+a[2])/3 )*ia )>>8) + ic;
4099 a += 4;
4100 b += 4;
4101 }
4102 }
4103 else {
4104 for (int j=0; j<npix; j++) {
4105 b[3] = (a[0]+a[1]+a[2])/3;
4106 a += 4;
4107 b += 4;
4108 }
4109 }
4110 }
4111
4112 #if 0
4113 static BOOL SameUV(TextureInfo &ta, TextureInfo &tb) {
4114 if (ta.uvwSource!=tb.uvwSource) return FALSE;
4115 if (ta.mapChannel!=tb.mapChannel) return FALSE;
4116 if (ta.tiling[0]!=tb.tiling[0]) return FALSE;
4117 if (ta.tiling[1]!=tb.tiling[1]) return FALSE;
4118 if (ta.tiling[2]!=tb.tiling[2]) return FALSE;
4119 if (ta.faceMap!=tb.faceMap) return FALSE;
4120 if (!(ta.textTM==tb.textTM)) return FALSE;
4121 return TRUE;
4122 }
4123 #endif
4124
4125 static Color whiteCol(1.0f, 1.0f, 1.0f);
4126
SetupGfxMultiMaps(TimeValue t,Material * mtl,MtlMakerCallback & cb)4127 void XRayMtl::SetupGfxMultiMaps(TimeValue t, Material *mtl, MtlMakerCallback &cb) {
4128 if (texHandleValid.InInterval(t)) {
4129 mtl->texture.SetCount(numTexHandlesUsed);
4130 for (int i=0; i<numTexHandlesUsed; i++) {
4131 if (texHandle[i]) {
4132 mtl->texture[i].textHandle = texHandle[i]->GetHandle();
4133 Texmap *tx = (*maps)[useSubForTex[i]].map;
4134 cb.GetGfxTexInfoFromTexmap(t, mtl->texture[i], tx );
4135 SetTexOps(mtl,i,texOpsType[i]);
4136 }
4137 }
4138 return;
4139 }
4140
4141 Texmap *tx[2];
4142 int diffChan = stdIDToChannel[ ID_DI ];
4143 int opacChan = stdIDToChannel[ ID_OP ];
4144 tx[0] = (*maps)[diffChan].IsActive()?(*maps)[diffChan].map:NULL;
4145 tx[1] = (*maps)[opacChan].IsActive()?(*maps)[opacChan].map:NULL;
4146
4147 int nsupport = cb.NumberTexturesSupported();
4148
4149 BITMAPINFO *bmi[NTEXHANDLES];
4150
4151 int nmaps=0;
4152 for (int i=0; i<NTEXHANDLES; i++) {
4153 if (tx[i]) nmaps ++;
4154 bmi[i] = NULL;
4155 }
4156 mtl->texture.SetCount(nmaps);
4157 if (nmaps==0)
4158 return;
4159 for (i=0; i<nmaps; i++)
4160 mtl->texture[i].textHandle = NULL;
4161 texHandleValid.SetInfinite();
4162 Interval valid;
4163 BOOL needDecal = FALSE;
4164 int ntx = 0;
4165 int op;
4166
4167 int forceW = 0;
4168 int forceH = 0;
4169 if (tx[0]) {
4170 cb.GetGfxTexInfoFromTexmap(t, mtl->texture[0], tx[0]);
4171 TextureInfo &ti = mtl->texture[0];
4172 if (ti.tiling[0]==GW_TEX_NO_TILING||ti.tiling[1]==GW_TEX_NO_TILING)
4173 needDecal = TRUE;
4174 op = needDecal?TXOP_ALPHABLEND:TXOP_MODULATE;
4175 bmi[0] = tx[0]->GetVPDisplayDIB(t,cb,valid,FALSE);
4176 if (bmi[0]) {
4177 texHandleValid &= valid;
4178 useSubForTex[0] = diffChan;
4179 ntx = 1;
4180 forceW = bmi[0]->bmiHeader.biWidth;
4181 forceH = bmi[0]->bmiHeader.biHeight;
4182 }
4183 }
4184 if (tx[1]) {
4185 cb.GetGfxTexInfoFromTexmap(t, mtl->texture[ntx], tx[1]);
4186 if (nsupport>ntx) {
4187 bmi[1] = tx[1]->GetVPDisplayDIB(t,cb,valid,TRUE);
4188 if (bmi[1]) {
4189 texHandleValid &= valid;
4190 StuffAlpha(bmi[1], (*maps)[opacChan].amount, GetOpacity(t),ntx?whiteCol:pShader->GetDiffuseClr(t));
4191 texHandle[ntx] = cb.MakeHandle(bmi[1]);
4192 bmi[1] = NULL;
4193 mtl->texture[ntx].textHandle = texHandle[ntx]->GetHandle();
4194 SetTexOps(mtl,ntx,TXOP_OPACITY);
4195 useSubForTex[ntx] = opacChan;
4196 ntx++;
4197 }
4198 }
4199 else {
4200 if (!needDecal) {
4201 TextureInfo ti;
4202 // if (SameUV(mtl->texture[0],mtl->texture[1])) {
4203 // Not really correct to combine channels for different UV's but what the heck.
4204 bmi[1] = tx[1]->GetVPDisplayDIB(t,cb,valid,TRUE, forceW, forceH);
4205 if (bmi[1]) {
4206 texHandleValid &= valid;
4207 StuffAlphaInto(bmi[1], bmi[0], (*maps)[opacChan].amount, GetOpacity(t));
4208 op = TXOP_OPACITY;
4209 free(bmi[1]);
4210 bmi[1] = NULL;
4211 }
4212 // }
4213 }
4214 }
4215 }
4216 if (bmi[0]) {
4217 texHandle[0] = cb.MakeHandle(bmi[0]);
4218 bmi[0] = NULL;
4219 mtl->texture[0].textHandle = texHandle[0]->GetHandle();
4220 SetTexOps(mtl,0,op);
4221 }
4222 mtl->texture.SetCount(ntx);
4223 numTexHandlesUsed = ntx;
4224 }
4225
4226 // end - dds- 04.27.00 - multiple map display support
4227
4228 //������������������������������������������������������������������������
4229 // Returns true if the evaluated color\value (output) is constant over all
4230 // possible inputs. This means all points of a face and all faces the
4231 // material is assigned to.
4232 // If it cannot determine the correct answer, it returns false
4233 //
IsOutputConst(ShadeContext & sc,int stdID)4234 bool XRayMtl::IsOutputConst
4235 (
4236 ShadeContext& sc, // describes context of evaluation
4237 int stdID // must be ID_AM, ect
4238 )
4239 {
4240 int channelID = StdIDToChannel( stdID );
4241 DbgAssert( 0 <= channelID && channelID < NumSubTexmaps() );
4242 if ( channelID < 0 || channelID >= NumSubTexmaps() )
4243 return false;
4244
4245 if ( SubTexmapOn( channelID ) )
4246 {
4247 Texmap* texMap = GetSubTexmap( channelID );
4248 DbgAssert( texMap != NULL );
4249 if ( texMap != NULL && texMap->IsOutputMeaningful( sc ) )
4250 // TODO: The texmap can be meaningful but constant
4251 return false;
4252 }
4253 return true;
4254 }
4255
4256 //������������������������������������������������������������������������
4257 // Evaluates the material on a single texmap channel.
4258 // For a mono channel, the value is copied in all 3 components of the
4259 // output color.
4260 //
EvalColorStdChannel(ShadeContext & sc,int stdID,Color & outClr)4261 bool XRayMtl::EvalColorStdChannel
4262 (
4263 ShadeContext& sc, // describes context of evaluation
4264 int stdID, // must be ID_AM, ect
4265 Color& outClr // output var
4266 )
4267 {
4268 switch ( stdID )
4269 {
4270 case ID_BU: // Bump (value 8)
4271 {
4272 return EvalBump( sc, outClr );
4273 }
4274 break;
4275
4276 case ID_RL: // Reflection (value 9)
4277 {
4278 return EvalReflection( sc, outClr );
4279 }
4280 break;
4281
4282 case ID_RR: // Refraction (value 10)
4283 {
4284 return EvalRefraction( sc, outClr );
4285 }
4286 break;
4287
4288 case ID_DP: // Displacement (value 11)
4289 {
4290 float outVal;
4291 bool bRes = EvalDisplacement( sc, outVal );
4292 if ( bRes )
4293 {
4294 outClr.r = outClr.g = outClr.b = outVal;
4295 }
4296 return bRes;
4297 }
4298 break;
4299
4300 // For everything else, there's a smart method
4301 case ID_AM: // Ambient (value 0)
4302 case ID_DI: // Diffuse (value 1)
4303 case ID_SP: // Specular (value 2)
4304 case ID_SH: // Shininess (value 3). In R3 and later this is called Glossiness.
4305 case ID_SS: // Shininess strength (value 4). In R3 and later this is called Specular Level.
4306 case ID_SI: // Self-illumination (value 5)
4307 case ID_OP: // Opacity (value 6)
4308 case ID_FI: // Filter color (value 7)
4309 {
4310 int id = StdIDToChannel( stdID );
4311 if ( id < 0 || id >= NumSubTexmaps() )
4312 return false;
4313 return EvalChannel( sc, id, outClr );
4314 }
4315 break;
4316
4317 default:
4318 // Should never happen
4319 //DbgAssert( false );
4320 return false;
4321 break;
4322 }
4323 return true;
4324 }
4325
4326 //������������������������������������������������������������������������
4327 // Evaluates the material on a single texmap channel.
4328 //
EvalMonoStdChannel(ShadeContext & sc,int stdID,float & outVal)4329 bool XRayMtl::EvalMonoStdChannel
4330 (
4331 ShadeContext& sc, // describes context of evaluation
4332 int stdID, // must be ID_AM, ect
4333 float& outVal // output var
4334 )
4335 {
4336 switch ( stdID )
4337 {
4338 case ID_BU: // Bump (value 8)
4339 {
4340 Color outClr;
4341 bool bRes = EvalBump( sc, outClr );
4342 if ( bRes )
4343 outVal = Intens( outClr );
4344 return bRes;
4345 }
4346 break;
4347
4348 case ID_RL: // Reflection (value 9)
4349 {
4350 return EvalReflection( sc, outVal );
4351 }
4352 break;
4353
4354 case ID_RR: // Refraction (value 10)
4355 {
4356 return EvalRefraction( sc, outVal );
4357 }
4358 break;
4359
4360 case ID_DP: // Displacement (value 11)
4361 {
4362 return EvalDisplacement( sc, outVal );
4363 }
4364 break;
4365
4366 // For everything else, there's a smart method
4367 case ID_AM: // Ambient (value 0)
4368 case ID_DI: // Diffuse (value 1)
4369 case ID_SP: // Specular (value 2)
4370 case ID_SH: // Shininess (value 3). In R3 and later this is called Glossiness.
4371 case ID_SS: // Shininess strength (value 4). In R3 and later this is called Specular Level.
4372 case ID_SI: // Self-illumination (value 5)
4373 case ID_OP: // Opacity (value 6)
4374 case ID_FI: // Filter color (value 7)
4375 {
4376 int id = StdIDToChannel( stdID );
4377 if ( id < 0 || id >= NumSubTexmaps() )
4378 return false;
4379 Color outClr;
4380 bool bRes = EvalChannel( sc, id, outClr );
4381 if ( bRes )
4382 outVal = Intens( outClr );
4383 return bRes;
4384 }
4385 break;
4386
4387 default:
4388 // Should never happen
4389 //DbgAssert( false );
4390 return false;
4391 break;
4392 }
4393 return true;
4394 }
4395
4396 //������������������������������������������������������������������������
4397 // channelID is supposed to be mapped from std subtexmap ID to subtexmap id
4398 //
EvalChannel(ShadeContext & sc,int channelID,Color & outClr)4399 bool XRayMtl::EvalChannel(ShadeContext& sc, int channelID, Color& outClr)
4400 {
4401 // For exmple, the Strauss shader doesn't support the ID_AM channel
4402 DbgAssert( 0 <= channelID && channelID < NumSubTexmaps() );
4403
4404 // Check if the mtl has or not a shader
4405 Shader* pShad = GetShader();
4406 DbgAssert( pShader != NULL );
4407 if ( pShad == NULL )
4408 {
4409 // Filter color and opacity values are managed by the stdmtl2?
4410 if ( channelID == StdIDToChannel(ID_FI) )
4411 {
4412 outClr = filter;
4413 return true;
4414 }
4415 else if ( channelID == StdIDToChannel(ID_FI) )
4416 {
4417 outClr.r = outClr.g = outClr.b = opacity;
4418 return true;
4419 }
4420 return false;
4421 }
4422
4423 // Get raw color\value from the shader
4424 IllumParams ip(0, NULL);
4425
4426 memset(static_cast<void*>(&ip), 0, sizeof(IllumParams) );
4427 // ip.mtlFlags = flags;
4428 pShad->GetIllumParams( sc, ip );
4429
4430 // Filter color and opacity values are managed by the stdmtl2?
4431 if ( channelID == StdIDToChannel(ID_FI) )
4432 ip.channels[channelID] = filter;
4433 else if ( channelID == StdIDToChannel(ID_OP) )
4434 {
4435 ip.channels[channelID].r = opacity;
4436 ip.channels[channelID].g = opacity;
4437 ip.channels[channelID].b = opacity;
4438 }
4439 long channelType = pShad->ChannelType( channelID );
4440
4441 // Evaluate the texture map
4442 if ( sc.doMaps )
4443 {
4444 if ( channelID == StdIDToChannel( ID_AM ) &&
4445 (flags & NEWSTDMTL_LOCK_ADTEX) == NEWSTDMTL_LOCK_ADTEX )
4446 {
4447 // Treat exceptional situations first
4448 //
4449 // Evaluat the ambient channel using the diffuse texmap
4450 // if AD texmap lock is on
4451
4452 long diffChanID = StdIDToChannel( ID_DI );
4453 long diffChanType = pShad->ChannelType( ID_DI );
4454 if ( diffChanID >= 0 &&
4455 SubTexmapOn( diffChanID ) &&
4456 ( diffChanType & SKIP_CHANNELS ) == 0 )
4457 {
4458 Texmap* texMap = GetSubTexmap( diffChanID );
4459 if ( texMap != NULL && texMap->IsOutputMeaningful( sc ) )
4460 {
4461 // Evaluate the diffuse channel first
4462 AColor diffColor;
4463 if ( (diffChanType & MONO_CHANNEL ) == MONO_CHANNEL )
4464 {
4465 diffColor.r = (*maps)[diffChanID].LerpEvalMono( sc, ip.channels[diffChanID].r );
4466 diffColor.g = diffColor.b = diffColor.r;
4467 diffColor.a = 0.0f;
4468 }
4469 else //if ( (diffChanType & CLR_CHANNEL ) == CLR_CHANNEL )
4470 {
4471 diffColor = (*maps)[diffChanID].Eval( sc );
4472 AlphaCompCol( ip.channels[diffChanID], diffColor );
4473 }
4474
4475 // Now evaluate the ambient channel
4476 if ( (channelType & MONO_CHANNEL ) == MONO_CHANNEL )
4477 {
4478 ip.channels[channelID].r = (*maps)[diffChanID].LerpEvalMono( sc, ip.channels[diffChanID].r );
4479 ip.channels[channelID].g = ip.channels[channelID].b = ip.channels[channelID].r;
4480 }
4481 else //if ( (channelType & CLR_CHANNEL ) == CLR_CHANNEL )
4482 AlphaCompCol( ip.channels[channelID], diffColor );
4483 }
4484 }
4485 }
4486 else
4487 {
4488 // Normal course of channel evaluation
4489
4490 if ( SubTexmapOn( channelID ) &&
4491 ( channelType & SKIP_CHANNELS ) == 0 )
4492 {
4493 Texmap* texMap = GetSubTexmap( channelID );
4494 if ( texMap != NULL && texMap->IsOutputMeaningful( sc ) )
4495 {
4496 if ( (channelType & MONO_CHANNEL ) == MONO_CHANNEL )
4497 {
4498 ip.channels[channelID].r = (*maps)[channelID].LerpEvalMono( sc, ip.channels[channelID].r );
4499 ip.channels[channelID].g = ip.channels[channelID].b = ip.channels[channelID].r;
4500 }
4501 else //if ( (channelType & CLR_CHANNEL ) == CLR_CHANNEL )
4502 {
4503 AColor c = (*maps)[channelID].Eval( sc );
4504 AlphaCompCol( ip.channels[channelID], c );
4505 }
4506 }
4507 }
4508 }
4509 }
4510
4511 // Return a potentialy texture mapped value
4512 outClr = ip.channels[channelID];
4513
4514 return true;
4515 }
4516
4517 //������������������������������������������������������������������������
4518 // Evaluates the bump map. Returns false if the result is not meaningful
4519 //
EvalBump(ShadeContext & sc,Color & outClr)4520 bool XRayMtl::EvalBump( ShadeContext& sc, Color& outClr )
4521 {
4522 int id = StdIDToChannel( ID_BU );
4523 if ( !ShouldEvalSubTexmap( sc, id ) )
4524 {
4525 outClr.Black();
4526 return false;
4527 }
4528
4529 Point3 dn = (*maps)[id].EvalNormalPerturb(sc);
4530 outClr = Normalize( ( sc.backFace ? -dn : dn ) );
4531
4532 return true;
4533 }
4534
4535 //������������������������������������������������������������������������
4536 // Evaluates reflection map as a color. Returns false if the result is not
4537 // meaningful
4538 //
EvalReflection(ShadeContext & sc,Color & outClr)4539 bool XRayMtl::EvalReflection( ShadeContext& sc, Color& outClr )
4540 {
4541 int id = StdIDToChannel( ID_RL );
4542 if ( !ShouldEvalSubTexmap( sc, id ) )
4543 {
4544 return false;
4545 }
4546
4547 AColor rcol;
4548 Texmap* reflmap = (*maps)[id].map;
4549 DbgAssert( reflmap != NULL );
4550 if ( reflmap->HandleOwnViewPerturb() )
4551 {
4552 sc.TossCache( reflmap );
4553 rcol = reflmap->EvalColor( sc );
4554 }
4555 else
4556 rcol = sc.EvalEnvironMap( reflmap, sc.ReflectVector() );
4557
4558 outClr.r = rcol.r;
4559 outClr.g = rcol.g;
4560 outClr.b = rcol.b;
4561
4562 return true;
4563 }
4564
4565 //������������������������������������������������������������������������
4566 // Evaluates reflection map as (mono) value. Returns false if the result
4567 // is not meaningful
4568 //
EvalReflection(ShadeContext & sc,float & outVal)4569 bool XRayMtl::EvalReflection( ShadeContext& sc, float& outVal )
4570 {
4571 int id = StdIDToChannel( ID_RL );
4572 if ( !ShouldEvalSubTexmap( sc, id ) )
4573 return false;
4574
4575 Texmap* reflmap = (*maps)[id].map;
4576 DbgAssert( reflmap != NULL );
4577 if ( reflmap->HandleOwnViewPerturb() )
4578 {
4579 sc.TossCache( reflmap );
4580 outVal = reflmap->EvalMono( sc );
4581 }
4582 else
4583 {
4584 AColor rcol;
4585 rcol = sc.EvalEnvironMap( reflmap, sc.ReflectVector() );
4586 outVal = Intens( rcol );
4587 }
4588
4589 return true;
4590 }
4591
4592 //������������������������������������������������������������������������
4593 // Evaluates refraction map as a color. Returns false if the result is not
4594 // meaningful
4595 //
EvalRefraction(ShadeContext & sc,Color & outClr)4596 bool XRayMtl::EvalRefraction( ShadeContext& sc, Color& outClr )
4597 {
4598 int id = StdIDToChannel( ID_RR );
4599 if ( !ShouldEvalSubTexmap( sc, id ) )
4600 return false;
4601
4602 AColor rcol;
4603 Texmap* refrmap = (*maps)[id].map;
4604 DbgAssert( refrmap != NULL );
4605 if ( refrmap->HandleOwnViewPerturb() )
4606 {
4607 rcol = refrmap->EvalColor( sc );
4608 }
4609 else
4610 rcol = sc.EvalEnvironMap( refrmap, sc.RefractVector( ioRefract ) );
4611
4612 outClr.r = rcol.r;
4613 outClr.g = rcol.g;
4614 outClr.b = rcol.b;
4615
4616 return true;
4617 }
4618
4619 //������������������������������������������������������������������������
4620 // Evaluates reflection map as (mono) value. Returns false if the result
4621 // is not meaningful
4622 //
EvalRefraction(ShadeContext & sc,float & outVal)4623 bool XRayMtl::EvalRefraction( ShadeContext& sc, float& outVal )
4624 {
4625 int id = StdIDToChannel( ID_RR );
4626 if ( !ShouldEvalSubTexmap( sc, id ) )
4627 return false;
4628
4629 Texmap* refrmap = (*maps)[id].map;
4630 DbgAssert( refrmap != NULL );
4631 if ( refrmap->HandleOwnViewPerturb() )
4632 {
4633 outVal = refrmap->EvalMono( sc );
4634 }
4635 else
4636 {
4637 AColor rcol;
4638 rcol = sc.EvalEnvironMap( refrmap, sc.RefractVector( ioRefract ) );
4639 outVal = Intens( rcol );
4640 }
4641
4642 return true;
4643 }
4644
4645 //������������������������������������������������������������������������
4646 // Evaluates Displacement map as a color. Returns false if the result is not
4647 // meaningful
4648 //
EvalDisplacement(ShadeContext & sc,float & outVal)4649 bool XRayMtl::EvalDisplacement( ShadeContext& sc, float& outVal )
4650 {
4651 int id = StdIDToChannel( ID_DP );
4652 if ( !ShouldEvalSubTexmap( sc, id ) )
4653 return false;
4654
4655 outVal = (*maps)[id].EvalMono(sc);
4656 return true;
4657 }
4658
4659 //������������������������������������������������������������������������
4660 // Helper method
4661 //
ShouldEvalSubTexmap(ShadeContext & sc,int id)4662 bool XRayMtl::ShouldEvalSubTexmap( ShadeContext& sc, int id )
4663 {
4664 if ( id >= 0 && id < NumSubTexmaps() &&
4665 sc.doMaps && SubTexmapOn( id ) )
4666 {
4667 Texmap* texMap = GetSubTexmap( id );
4668 if ( texMap != NULL && texMap->IsOutputMeaningful( sc ) )
4669 return true;
4670 }
4671
4672 return false;
4673 }
4674
4675 // XRay Part
LoadXRayShaderList()4676 void XRayMtl::LoadXRayShaderList()
4677 {
4678 XRayMtl::EShaders.clear ();
4679 XRayMtl::CShaders.clear ();
4680 XRayMtl::GameMtls.clear ();
4681 int e_res = LoadBlenderList (XRayMtl::EShaders);
4682 int c_res = LoadShaderLCList(XRayMtl::CShaders);
4683 int g_res = LoadGameMtlList (XRayMtl::GameMtls);
4684 if ((e_res==-1)||(c_res==-1)||(g_res==-1))
4685 {
4686
4687 xray_re::msg("Can't load shader files!\nGame material will work incorrectly.");
4688 THROW;
4689 }
4690 }
4691
UnloadXRayShaderList()4692 void XRayMtl::UnloadXRayShaderList()
4693 {
4694 ClearList(XRayMtl::EShaders);
4695 ClearList(XRayMtl::CShaders);
4696 ClearList(XRayMtl::GameMtls);
4697 }
4698
SetEShaderIndx(long indx)4699 void XRayMtl::SetEShaderIndx( long indx )
4700 {
4701 pb_xray->SetValue(std2_eshader_type, 0, indx<0 ? 0 : indx );
4702 eshaderId = indx;
4703 }
SetCShaderIndx(long indx)4704 void XRayMtl::SetCShaderIndx( long indx )
4705 {
4706 pb_xray->SetValue(std2_cshader_type, 0, indx<0 ? 0 : indx );
4707 cshaderId = indx;
4708 }
SetGameMtlIndx(long indx)4709 void XRayMtl::SetGameMtlIndx( long indx )
4710 {
4711 pb_xray->SetValue(std2_gamemtl_type, 0, indx<0 ? 0 : indx );
4712 gamemtlId = indx;
4713 }
GetEShader(DWORD i)4714 TCHAR* XRayMtl::GetEShader (DWORD i)
4715 {
4716 return (i<EShaders.size())?(TCHAR*)EShaders[i]:0;
4717 }
GetCShader(DWORD i)4718 TCHAR* XRayMtl::GetCShader (DWORD i)
4719 {
4720 return (i<CShaders.size())?(TCHAR*)CShaders[i]:0;
4721 }
GetGameMtl(DWORD i)4722 TCHAR* XRayMtl::GetGameMtl (DWORD i)
4723 {
4724 return (i<GameMtls.size())?(TCHAR*)GameMtls[i]:0;
4725 }
4726
FindEShader(LPCSTR name)4727 int XRayMtl::FindEShader(LPCSTR name)
4728 {
4729 if (!name) return -1;
4730 for (LPSTR_vec_it it=XRayMtl::EShaders.begin(); it!=XRayMtl::EShaders.end(); it++)
4731 if (0==strcmp(*it,name)) return it-XRayMtl::EShaders.begin();
4732 return -1;
4733 }
4734
FindCShader(LPCSTR name)4735 int XRayMtl::FindCShader(LPCSTR name)
4736 {
4737 if (!name) return -1;
4738 for (LPSTR_vec_it it=XRayMtl::CShaders.begin(); it!=XRayMtl::CShaders.end(); it++)
4739 if (0==strcmp(*it,name)) return it-XRayMtl::CShaders.begin();
4740 return -1;
4741 }
4742
FindGameMtl(LPCSTR name)4743 int XRayMtl::FindGameMtl(LPCSTR name)
4744 {
4745 if (!name) return -1;
4746 for (LPSTR_vec_it it=XRayMtl::GameMtls.begin(); it!=XRayMtl::GameMtls.end(); it++)
4747 if (0==strcmp(*it,name)) return it-XRayMtl::GameMtls.begin();
4748 return -1;
4749 }
4750