1 //////////////////////////////////////////////////////////////////////
2 //
3 // Shader UI Utilities
4 //
5 #include "shadersPch.h"
6 #include "shadersRc.h"
7 #include "shaders.h"
8 #include "shaderUtil.h"
9 #include "iColorMan.h"
10 #include "toneop.h"
11
12 #include "3dsmaxport.h"
13
14 static const float Pi = 3.1415926f;
15 static const float Pi2 = Pi * Pi;
16 static const float Pi2Ivr = 1.0f / Pi2;
17 static const float PiIvr = 1.0f / Pi;
18
19
OrenNayarIllum(Point3 & N,Point3 & L,Point3 & V,float rough,Color & rho,float * pDiffIntensOut,float NL)20 Color OrenNayarIllum( Point3& N, Point3& L, Point3& V, float rough, Color& rho, float* pDiffIntensOut, float NL )
21 {
22 // float a = NL >= -1.0f ? float( acos( NL / Len(L) )) : AngleBetween( N, L );
23 // use the non-uniform scale corrected NL
24 if ( NL < -1.0f )
25 NL = Dot( N, L );
26 // float a = float( acos( NL / Len(L) )) ;
27 float a = 0.0f;
28 if( NL < 0.9999f )
29 a = acosf( NL );
30 a = Bound( a, -Pi*0.49f, Pi*0.49f );
31 float NV = Dot( N, V );
32 // need this to accomodate double sided materials
33 if( NV < 0.0f ){
34 NV = -NV;
35 V = -V;
36 }
37 float b = 0.0f;
38 if( NV < 0.9999f )
39 b = acosf( NV );
40 MinMax( b, a ); // b gets min, a gets max
41
42
43 //N.V is the length of the projection of v onto n; times N is a vector along N of that length
44 // V - that pt gives a tangent vector in the plane of N, for measuring phi
45 Point3 tanV = V - N * NV;
46 Point3 tanL = L - N * NL;
47 float w = Len( tanV ) * Len( tanL );
48 float cosDPhi = (Abs(w) < 1e-4) ? 1.0f : Dot( tanV, tanL ) / w;
49 cosDPhi = Bound( cosDPhi, -1.0f, 1.0f );
50
51
52 // float bCube = (cosDPhi >= 0.0f) ? 0.0f : Cube( 2.0f * b * PiIvr );
53 float bCube = (cosDPhi >= 0.0f) ? Cube( 2.0f * -b * PiIvr ) : Cube( 2.0f * b * PiIvr );
54
55 // these three can be pre-calc'd for speed
56 float sigma2 = Sqr( rough );
57 float sigma3 = sigma2 / (sigma2 + 0.09f);
58 float c1 = 1.0f - 0.5f * (sigma2 / (sigma2 + 0.33f));
59
60 float c2 = 0.45f * sigma3 * (float(sin(a)) - bCube);
61 float c3 = 0.125f * sigma3 * Sqr( 4.0f * a * b * Pi2Ivr );
62 float tanB = float( tan(b) );
63 float tanAB = float( tan( (a+b) * 0.5f ));
64 tanB = Bound( tanB, -100.0f, 100.0f );
65 tanAB = Bound( tanAB, -100.0f, 100.0f );
66
67 Color o;
68 float l1 = ( c1 + c2 * cosDPhi * tanB + c3 * (1.0f - Abs( cosDPhi )) * tanAB );
69 float l2 = 0.17f * (sigma2 / (sigma2 + 0.13f)) * ( 1.0f - cosDPhi * Sqr( 2.0f * b * PiIvr ));
70 if( pDiffIntensOut )
71 *pDiffIntensOut = l1+l2;
72 o.r = l1 * rho.r + l2 * Sqr( rho.r );
73 o.g = l1 * rho.g + l2 * Sqr( rho.g );
74 o.b = l1 * rho.b + l2 * Sqr( rho.b );
75 return UBound( o );
76
77 }
78
79 // perpendicular to N, in the U (reference) direction
GetTangent(ShadeContext & sc,int uvChan)80 Point3 GetTangent( ShadeContext &sc, int uvChan )
81 {
82 // Point3 basisVecs[ 3 ];
83 // sc.DPdUVW( basisVecs, uvChan ); // 0 is vtxclr, 1..n is uv channels, max_meshmaps in mesh.h
84 // Point3 U = Normalize( basisVecs[0] );
85
86 Point3 U = sc.VectorFrom( Point3( 0.01f, 0.0f, 1.0f ), REF_OBJECT );
87 //Retry:
88 U = Normalize( U );
89
90 Point3 N = sc.Normal(); //assumed normalized
91
92 // the line between the tip of vec[0] and its projection on N is tangent
93 float UN = Dot( U, N );
94 // if ( Abs(UN) > 0.9999999f ){
95 // U = sc.VectorFrom( Point3( 0.01f, 1.0f, 0.0f ), REF_OBJECT );
96 // goto Retry;
97 // }
98 Point3 T = U - N * UN;
99 T = Normalize( T );
100 return T;
101 }
102
103
104 // specular reflectivity, no colors yet, all vectors assumed normalized
GaussHighlight(float gloss,float aniso,float orient,Point3 & N,Point3 & V,Point3 & L,Point3 & T,float * pNL)105 float GaussHighlight( float gloss, float aniso, float orient,
106 Point3& N, Point3& V, Point3& L, Point3& T, float* pNL )
107 {
108 float out = 0.0f;
109
110 float asz = (1.0f - gloss) * ALPHA_SZ;
111 float ax = ALPHA_MIN + asz;
112 float ay = ALPHA_MIN + asz * (1.0f-aniso);
113 // DbgAssert( ax >= 0.0f && ay >= 0.0f );
114 LBound( ax ); LBound( ay );
115
116 Point3 H = Normalize(L - V); // (L + -V)/2
117 float NH = DotProd(N, H);
118 if (NH > 0.0f) {
119 float axy = /* normalizeOn ? ax * ay : */ DEFAULT_GLOSS2;
120 float norm = 1.0f / (4.0f * PI * axy );
121 float NV = -DotProd(N, V );
122 if ( NV <= 0.001f)
123 NV = 0.001f;
124
125 float NL = pNL ? *pNL : DotProd( N, L );
126 float g = 1.0f / (float)sqrt( NL * NV );
127 if ( g > 3.0f ) g = 3.0f;
128
129 // Apply Orientation rotation here
130 float or = orient * 180.0f;
131 Point3 T1 = T;
132 if ( or != 0.0f )
133 T1 = RotateVec( T, N, DegToRdn(or));
134
135 // get binormal
136 Point3 B = CrossProd( T1, N );
137
138 float x = Dot( H, T1 ) / ax;
139 float y = Dot( H, B ) / ay;
140 float e = (float)exp( -2.0 * (x*x + y*y) / (1.0+NH) );
141
142 out = norm * g * e;
143 }
144 return SPEC_MAX * out; // does not have speclev or light color or kL
145 }
146
GaussHiliteCurve2(float x,float y,float sLevel,float gloss,float aniso)147 float GaussHiliteCurve2( float x, float y, float sLevel, float gloss, float aniso )
148 {
149 double axy = DEFAULT_GLOSS2;
150 double asz = (1.0f - gloss) * ALPHA_SZ;
151 double ax = ALPHA_MIN + asz;
152 double ay = ALPHA_MIN + asz * (1.0f - aniso) ;
153 double ax2 = ax * ax;
154 double ay2 = ay * ay;
155
156 double t, a;
157 double l = sqrt( x*x + y*y );
158 if ( l == 0.0 ) {
159 a = t = 0.0;
160 } else {
161 x /= float(l); y /= float(l);
162 t = tan( l*PI*0.5 );
163 a = x*x/ax2 + y*y/ay2;
164 }
165 return SPEC_MAX * sLevel*(float)(exp( -(t * t) * a ) / (4.0 * PI * axy));
166 }
167
168 //////////////////////////////////////////////////////////////////////////////
169 //
170 // Combine Components....Adding & compositing
171 //
172 #define COMBINE_ADD(ip) \
173 ((ip).finalAttenuation * ((ip).ambIllumOut + (ip).diffIllumOut + (ip).selfIllumOut) \
174 + (ip).specIllumOut + (ip).reflIllumOut + (ip).transIllumOut)
175
CombineComponentsAdd(IllumParams & ip)176 void CombineComponentsAdd( IllumParams& ip )
177 {
178 ip.finalC = COMBINE_ADD(ip);
179 }
180
ChooseSpecularMethod(TimeValue t,RenderGlobalContext * rgc)181 void CombineComponentsCompShader::ChooseSpecularMethod(TimeValue t, RenderGlobalContext* rgc)
182 {
183 useComposite = true;
184 if (rgc == NULL) {
185 ToneOperatorInterface* tint = static_cast<ToneOperatorInterface*>(
186 GetCOREInterface(TONE_OPERATOR_INTERFACE));
187 if (tint != NULL) {
188 ToneOperator* top = tint->GetToneOperator();
189 if (top != NULL && top->Active(t))
190 useComposite = false;
191 }
192 } else {
193 ToneOperator* top = rgc->pToneOp;
194 if (top != NULL && top->Active(t))
195 useComposite = false;
196 }
197 }
198
CombineComponents(ShadeContext & sc,IllumParams & ip)199 void CombineComponentsCompShader::CombineComponents( ShadeContext &sc, IllumParams& ip )
200 {
201 if (useComposite) {
202 Color spec, diff, rem;
203 spec = ip.specIllumOut + ip.reflIllumOut;
204 rem = 1.0f - spec;
205 rem = Bound( rem );
206 diff = ip.ambIllumOut + ip.diffIllumOut + ip.selfIllumOut;
207 ip.finalC = spec + ip.finalAttenuation * rem * diff + rem * ip.transIllumOut;
208 } else {
209 ip.finalC = COMBINE_ADD(ip);
210 }
211 }
212
GetInterface(Interface_ID id)213 BaseInterface* CombineComponentsCompShader::GetInterface(Interface_ID id)
214 {
215 if (id == ISPECULAR_COMPOSITE_SHADER_ID)
216 return static_cast<ISpecularCompositeShader*>(this);
217 return NULL;
218 }
219
220
221 //////////////////////////////////////////////////////////////////////////////
222 //
223 // transpColor utility
224 //
transpColor(ULONG type,float opac,Color & filt,Color & diff)225 Color transpColor( ULONG type, float opac, Color& filt, Color& diff )
226 {
227 // Compute the color of the transparent filter color
228 if ( type == TRANSP_ADD ) { // flags & STDMTL_ADD_TRANSP) {
229 float f = 1.0f - opac;
230 return Color(f, f, f);
231
232 } else if ( type == TRANSP_FILTER ) { //flags & STDMTL_FILT_TRANSP ){
233 // Transparent Filter color mapping
234 if (opac>0.5f) {
235 // darken as opac goes ( 0.5--> 1.0)
236 // so that max component reaches 0.0f when opac reaches 1.0
237 // find max component of filt
238 float m = Max(filt);
239 float d = 2.0f*(opac-.5f)*m;
240 Color fc = filt-d;
241 fc = LBound( fc );
242 return fc;
243 } else {
244 // lighten as opac goes ( 0.5--> 0.0)
245 // so that min component reaches 1.0f when opac reaches 1.0
246 // find min component of filt
247 float m = Min(filt);
248 float d = (1.0f-2.0f*opac)*(1.0f-m);
249 Color fc = filt+d;
250 fc = UBound( fc );
251 return fc;
252 }
253
254 } else {
255 // original 3DS transparency
256 Color f = (1.0f-diff);
257 return (1.0f-opac)*f;
258 }
259
260 }
261
262 //////////////////////////////////////////////////////////////////////////////
263 //
264 // UI utilities
265 //
266 static HIMAGELIST hLockButtons = NULL;
267 extern HINSTANCE hInstance;
268
269 // mjm - begin - 5.10.99
270 class ResourceDelete
271 {
272 public:
ResourceDelete()273 ResourceDelete() {}
~ResourceDelete()274 ~ResourceDelete() { if (hLockButtons) ImageList_Destroy(hLockButtons); }
275 };
276
277 static ResourceDelete theResourceDelete;
278 // mjm - end
279
IsButtonChecked(HWND hWnd,int id)280 BOOL IsButtonChecked(HWND hWnd,int id)
281 {
282 ICustButton *iBut;
283 BOOL res;
284 iBut = GetICustButton(GetDlgItem(hWnd,id));
285 res = iBut->IsChecked();
286 ReleaseICustButton(iBut);
287 return res;
288 }
289
CheckButton(HWND hWnd,int id,BOOL check)290 void CheckButton(HWND hWnd,int id, BOOL check) {
291 ICustButton *iBut;
292 iBut = GetICustButton(GetDlgItem(hWnd,id));
293 if( iBut )
294 iBut->SetCheck(check);
295 ReleaseICustButton(iBut);
296 }
297
SetupLockButton(HWND hWnd,int id,BOOL check)298 void SetupLockButton(HWND hWnd,int id, BOOL check)
299 {
300 ICustButton *iBut;
301 iBut = GetICustButton(GetDlgItem(hWnd,id));
302 iBut->SetImage(hLockButtons,0,1,0,1,16,15);
303 iBut->SetType(CBT_CHECK);
304 ReleaseICustButton(iBut);
305 }
306
SetupPadLockButton(HWND hWnd,int id,BOOL check)307 void SetupPadLockButton(HWND hWnd,int id, BOOL check) {
308 ICustButton *iBut;
309 iBut = GetICustButton(GetDlgItem(hWnd,id));
310 iBut->SetImage(hLockButtons,2,2,2,2,16,15);
311 iBut->SetType(CBT_CHECK);
312 ReleaseICustButton(iBut);
313 }
314
LoadStdShaderResources()315 void LoadStdShaderResources()
316 {
317 static BOOL loaded=FALSE;
318 if (loaded) return;
319 loaded = TRUE;
320 HBITMAP hBitmap, hMask;
321
322 hLockButtons = ImageList_Create(16, 15, TRUE, 2, 0);
323 hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_DMTL_BUTTONS));
324 hMask = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_DMTL_MASKBUTTONS));
325 ImageList_Add(hLockButtons,hBitmap,hMask);
326 DeleteObject(hBitmap);
327 DeleteObject(hMask);
328 }
329
330
331 //-HiLite Curve Control------------------------------------------------------
332
VertLine(HDC hdc,int x,int ystart,int yend)333 static void VertLine(HDC hdc,int x, int ystart, int yend)
334 {
335 MoveToEx(hdc, x, ystart, NULL);
336 if (ystart <= yend)
337 LineTo(hdc, x, yend+1);
338 else
339 LineTo(hdc, x, yend-1);
340 }
341
DrawHilite(HDC hdc,Rect & rect,Shader * pShader)342 void DrawHilite(HDC hdc, Rect& rect, Shader* pShader )
343 {
344 int w,h,npts,xcen,ybot,ytop,ylast,i,iy;
345
346 HPEN linePen = (HPEN)GetStockObject(WHITE_PEN);
347 HPEN fgPen = CreatePen(PS_SOLID,0,GetCustSysColor(COLOR_BTNFACE));
348 HPEN bgPen = CreatePen(PS_SOLID,0,GetCustSysColor(COLOR_BTNSHADOW));
349
350 w = rect.w();
351 h = rect.h()-3;
352 npts = (w-2)/2;
353 xcen = rect.left+npts;
354 ybot = rect.top+h;
355 ytop = rect.top+2;
356 ylast = -1;
357 for (i=0; i<npts; i++) {
358 float v = pShader->EvalHiliteCurve( (float)i/((float)npts*2.0f) );
359 if (v>2.0f) v = 2.0f; // keep iy from wrapping
360 iy = ybot-(int)(v*((float)h-2.0f));
361
362 if (iy<ytop) iy = ytop;
363
364 SelectPen(hdc, fgPen);
365 VertLine(hdc,xcen+i,ybot,iy);
366 VertLine(hdc,xcen-i,ybot,iy);
367
368 if (iy-1>ytop) {
369 // Fill in above curve
370 SelectPen(hdc,bgPen);
371 VertLine(hdc,xcen+i, ytop, iy-1);
372 VertLine(hdc,xcen-i, ytop, iy-1);
373 }
374 if (ylast>=0) {
375 SelectPen(hdc,linePen);
376 VertLine(hdc,xcen+i-1,iy-1,ylast);
377 VertLine(hdc,xcen-i+1,iy-1,ylast);
378 }
379
380 ylast = iy;
381 }
382
383 SelectObject( hdc, linePen );
384 DeleteObject(fgPen);
385 DeleteObject(bgPen);
386 WhiteRect3D(hdc, rect, 1);
387 }
388
HiliteWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)389 LRESULT CALLBACK HiliteWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
390 {
391 LONG_PTR id = GetWindowLongPtr(hwnd,GWLP_ID);
392 HWND hwParent = GetParent(hwnd);
393 ShaderParamDlg *theDlg = DLGetWindowLongPtr<ShaderParamDlg *>(hwParent);
394 if (theDlg==NULL) return FALSE;
395
396 switch (msg) {
397 case WM_COMMAND:
398 case WM_MOUSEMOVE:
399 case WM_LBUTTONUP:
400 case WM_CREATE:
401 case WM_DESTROY:
402 break;
403
404 case WM_PAINT:
405 {
406 PAINTSTRUCT ps;
407 Rect rect;
408 HDC hdc = BeginPaint( hwnd, &ps );
409 if (!IsRectEmpty(&ps.rcPaint)) {
410 GetClientRect( hwnd, &rect );
411 Shader* pShader = theDlg->GetShader();
412 DrawHilite(hdc, rect, pShader );
413 }
414 EndPaint( hwnd, &ps );
415 }
416 break;
417 }
418 return DefWindowProc(hwnd,msg,wParam,lParam);
419 }
420
421 // iso projection of 2 orthogonal highlight curves
DrawHilite2(HDC hdc,Rect & rect,Shader * pShader,int layer)422 void DrawHilite2(HDC hdc, Rect& rect, Shader* pShader, int layer )
423 {
424 int w,h,npts,xcen,ybot,ytop,ylast,i,iy, off, vals[200];
425 float ybr, ybl;
426
427 HPEN linePen = (HPEN)GetStockObject(WHITE_PEN);
428 HPEN fgPen = CreatePen(PS_SOLID,0,GetCustSysColor(COLOR_BTNFACE));
429 HPEN fg2Pen = CreatePen(PS_SOLID,0,GetCustSysColor(COLOR_BTNHILIGHT));
430 HPEN bgPen = CreatePen(PS_SOLID,0,GetCustSysColor(COLOR_BTNSHADOW));
431
432 w = rect.w();
433 assert( w/2 < 200 ); // 200 vals saved for visibility
434 h = rect.h()-3;
435 npts = (w-2)/2;
436 off = h / 6;
437 float slope = float(h-off-off)/w;
438 ybot = rect.top+h;
439 ytop = rect.top+2;
440
441 // first the X curve
442 ybr = ybl = float(rect.top+h - 2.5* off);
443 xcen = rect.left+npts;
444 ylast = -1;
445 for (i=0; i<npts; i++) {
446 float v = pShader->EvalHiliteCurve2( (float)i/((float)npts*2.0f), 0.0f, layer );
447 if (v>2.0f) v = 2.0f; // keep iy from wrapping
448 iy = (int)(v* 0.6f * ((float)h-2.0f));
449
450 int r = int( ybr + 0.5f );
451 if ( r > ybot ) r = ybot;
452 int l = int( ybl + 0.5f );
453 if ( l > ybot ) l = ybot;
454
455 int ry = r - iy;
456 if (ry<ytop) ry = ytop;
457 if (ry>ybot) ry = ybot;
458 vals[i] = ry; // save for visibility
459
460 int ly = l - iy;
461 if (ly<ytop) ly = ytop;
462 if (ly>ybot) ly = ybot;
463
464 SelectPen(hdc, fgPen);
465 VertLine(hdc,xcen+i, r, ry); // start at center & spread out on both sides
466 VertLine(hdc,xcen-i, l, ly);
467
468 SelectPen(hdc,bgPen); // Fill in below baseline
469 VertLine(hdc,xcen+i, ybot, r+1);
470 VertLine(hdc,xcen-i, ybot, l+1);
471
472 VertLine(hdc,xcen+i, ytop, ry-1);
473 VertLine(hdc,xcen-i, ytop, ly-1); // fill in above curve
474
475 // if (ylast>=0) {
476 // SelectPen(hdc,linePen);
477 // VertLine(hdc, xcen+i-1, iy-1, ylast); // white dot marks curve
478 // VertLine(hdc, xcen-i+1, iy-1, ylast);
479 // }
480
481 ylast = iy;
482 ybr += slope;
483 ybl += -slope;
484 }
485
486 // now do the Y curve
487 ybr = ybl = float(rect.top+h - 2.5* off);
488 xcen = rect.left+npts - 1;
489 ylast = -1;
490 for (i=0; i < npts; i++) {
491 float v = pShader->EvalHiliteCurve2( 0.0f, (float)i/((float)npts*2.0f), layer );
492 if (v>2.0f) v = 2.0f; // keep iy from wrapping
493 iy = (int)(v* 0.6f * ((float)h-2.0f));
494
495 int r = int( ybr + 0.5f );
496 if ( r > ybot ) r = ybot;
497 int l = int( ybl + 0.5f );
498 if ( l > ybot ) l = ybot;
499
500 int ry = r - iy;
501 if (ry<ytop) ry = ytop;
502 if (ry>ybot) ry = ybot;
503
504 int ly = l - iy;
505 if (ly<ytop) ly = ytop;
506 if (ly>ybot) ly = ybot;
507
508 SelectPen(hdc, fg2Pen);
509 VertLine(hdc,xcen-i, l, ly); // left side always visible..in front
510
511 if ( r <= vals[i] )
512 VertLine(hdc,xcen+i, r, ry); // start at center & spread out on both sides
513 else if ( ry <= vals[i] )
514 VertLine(hdc,xcen+i, vals[i]-1, ry); // start at center & spread out on both sides
515
516 // if (ylast>=0) {
517 // SelectPen(hdc,linePen);
518 // VertLine(hdc, xcen+i-1, iy-1, ylast); // white dot marks curve
519 // VertLine(hdc, xcen-i+1, iy-1, ylast);
520 // }
521
522 ylast = iy;
523 ybr += -slope;
524 ybl += slope;
525 }
526
527 SelectObject( hdc, linePen );
528 DeleteObject(fgPen);
529 DeleteObject(fg2Pen);
530 DeleteObject(bgPen);
531 WhiteRect3D(hdc, rect, 1);
532 }
533
Hilite2WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)534 LRESULT CALLBACK Hilite2WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
535 {
536 LONG_PTR id = GetWindowLongPtr(hwnd,GWLP_ID);
537 HWND hwParent = GetParent(hwnd);
538 ShaderParamDlg *theDlg = DLGetWindowLongPtr<ShaderParamDlg *>(hwParent);
539 if (theDlg==NULL) return FALSE;
540
541 switch (msg) {
542 case WM_COMMAND:
543 case WM_MOUSEMOVE:
544 case WM_LBUTTONUP:
545 case WM_CREATE:
546 case WM_DESTROY:
547 break;
548
549 case WM_PAINT:
550 {
551 PAINTSTRUCT ps;
552 Rect rect;
553 HDC hdc = BeginPaint( hwnd, &ps );
554 if (!IsRectEmpty(&ps.rcPaint)) {
555 GetClientRect( hwnd, &rect );
556 Shader* pShader = theDlg->GetShader();
557 DrawHilite2(hdc, rect, pShader );
558 }
559 EndPaint( hwnd, &ps );
560 }
561 break;
562 }
563 return DefWindowProc(hwnd,msg,wParam,lParam);
564 }
565
Hilite2Layer1WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)566 LRESULT CALLBACK Hilite2Layer1WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
567 {
568 LONG_PTR id = GetWindowLongPtr(hwnd,GWLP_ID);
569 HWND hwParent = GetParent(hwnd);
570 ShaderParamDlg *theDlg = DLGetWindowLongPtr<ShaderParamDlg *>(hwParent);
571 if (theDlg==NULL) return FALSE;
572
573 switch (msg) {
574 case WM_PAINT:
575 {
576 PAINTSTRUCT ps;
577 Rect rect;
578 HDC hdc = BeginPaint( hwnd, &ps );
579 if (!IsRectEmpty(&ps.rcPaint)) {
580 GetClientRect( hwnd, &rect );
581 Shader* pShader = theDlg->GetShader();
582 DrawHilite2(hdc, rect, pShader, 1 );
583 }
584 EndPaint( hwnd, &ps );
585 }
586 break;
587 }
588 return DefWindowProc(hwnd,msg,wParam,lParam);
589 }
590
Hilite2Layer2WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)591 LRESULT CALLBACK Hilite2Layer2WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
592 {
593 LONG_PTR id = GetWindowLongPtr(hwnd,GWLP_ID);
594 HWND hwParent = GetParent(hwnd);
595 ShaderParamDlg *theDlg = DLGetWindowLongPtr<ShaderParamDlg *>(hwParent);
596 if (theDlg==NULL) return FALSE;
597
598 switch (msg) {
599 case WM_PAINT:
600 {
601 PAINTSTRUCT ps;
602 Rect rect;
603 HDC hdc = BeginPaint( hwnd, &ps );
604 if (!IsRectEmpty(&ps.rcPaint)) {
605 GetClientRect( hwnd, &rect );
606 Shader* pShader = theDlg->GetShader();
607 DrawHilite2(hdc, rect, pShader, 2 );
608 }
609 EndPaint( hwnd, &ps );
610 }
611 break;
612 }
613 return DefWindowProc(hwnd,msg,wParam,lParam);
614 }
615
UpdateHilite(HWND hwHilite,Shader * pShader,int layer)616 void UpdateHilite( HWND hwHilite, Shader* pShader, int layer )
617 {
618 Rect r;
619
620 HDC hdc = GetDC( hwHilite );
621 GetClientRect( hwHilite, &r );
622 DrawHilite( hdc, r, pShader );
623 ReleaseDC( hwHilite, hdc );
624 }
625
626
UpdateHilite2(HWND hwHilite,Shader * pShader,int layer)627 void UpdateHilite2( HWND hwHilite, Shader* pShader, int layer )
628 {
629 Rect r;
630
631 HDC hdc = GetDC( hwHilite );
632 GetClientRect( hwHilite, &r );
633 DrawHilite2( hdc, r, pShader, layer );
634 ReleaseDC( hwHilite, hdc );
635 }
636
637
638 ////////////////////////////////////////////////////////////////////////
639
GetMtlColor(int i,Shader * pShader)640 Color GetMtlColor( int i, Shader* pShader )
641 {
642 switch(i) {
643 case 0: return pShader->GetAmbientClr(0,0);
644 case 1: return pShader->GetDiffuseClr(0,0);
645 case 2: return pShader->GetSpecularClr(0,0);
646 case 3: return pShader->GetSelfIllumClr(0,0);
647 default: return Color(0,0,0);
648 }
649 }
650
GetColorName(int i)651 TCHAR *GetColorName( int i )
652 {
653 switch(i) {
654 case 0: return GetString(IDS_DS_AMBIENT);
655 case 1: return GetString(IDS_DS_DIFFUSE);
656 case 2: return GetString(IDS_DS_SPECULAR);
657 case 3: return GetString(IDS_KE_SELFILLUM_CLR);
658 default: return GetString(IDS_KE_NOSUCH_CLR);
659 }
660 }
661
SetMtlColor(int i,Color c,Shader * pShader,IColorSwatch ** cs,TimeValue t)662 void SetMtlColor(int i, Color c, Shader* pShader, IColorSwatch** cs, TimeValue t)
663 {
664 switch(i) {
665 case 0: //ambient
666 pShader->SetAmbientClr(c,t);
667 if ( pShader->GetLockAD() ){
668 pShader->SetDiffuseClr(c, t);
669 cs[1]->SetColor( c );
670 if (pShader->GetLockDS() ){
671 pShader->SetSpecularClr(c,t);
672 cs[2]->SetColor(c);
673 }
674 }
675 break;
676 case 1: //diffuse
677 pShader->SetDiffuseClr(c,t);
678 if (pShader->GetLockAD() ){
679 pShader->SetAmbientClr(c,t);
680 cs[0]->SetColor(c);
681 }
682 if ( pShader->GetLockDS() ){
683 pShader->SetSpecularClr(c,t);
684 cs[2]->SetColor(c);
685 }
686 break;
687 case 2: // specular
688 pShader->SetSpecularClr(c,t);
689 if (pShader->GetLockDS() ){
690 pShader->SetDiffuseClr(c,t);
691 cs[1]->SetColor(c);
692 if (pShader->GetLockAD() ){
693 pShader->SetAmbientClr(c,t);
694 cs[0]->SetColor(c);
695 }
696 }
697 break;
698 case 3:
699 pShader->SetSelfIllumClr(c,t);
700 break;
701 }
702 }
703
704 ///////////////////////////////////////////////////////////////////////////
705 // utility math routines
706 //
RotateVec(Point3 & p,Point3 & a,float rdn)707 Point3 RotateVec( Point3& p, Point3& a, float rdn )
708 {
709 float c = float( cos( rdn ));
710 float t = 1 - c;
711 float s = float( sin( rdn ));
712 float txy = t * a.x * a.y;
713 float tyz = t * a.y * a.z;
714 float txz = t * a.x * a.z;
715 float sx = s * a.x;
716 float sy = s * a.y;
717 float sz = s * a.z;
718
719 Point3 out;
720 out.x = p.x *(t* a.x * a.x + c) + p.y * (txy - sz) + p.z * (txz + sy);
721 out.y = p.x *(txy + sz) + p.y * (t* a.y * a.y + c) + p.z * (tyz - sx);
722 out.z = p.x *(txz - sy) + p.y * (tyz + sx) + p.z * (t* a.z * a.z + c);
723
724 return out;
725 }
726