Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3956 lines
133 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: so_phong.c
  3. *
  4. * Routines to draw primitives
  5. *
  6. * Created: 10-16-1995
  7. * Author: Hock San Lee [hockl]
  8. *
  9. * Copyright (c) 1995 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include <fixed.h>
  14. #include <glmath.h>
  15. #ifdef GL_WIN_phong_shading
  16. #ifdef _X86_
  17. #include <gli386.h>
  18. #endif
  19. #define __FASTEST
  20. // Macros
  21. #define DOT(m,a,b) m = (a)->x*(b)->x + (a)->y*(b)->y + (a)->z*(b)->z
  22. #define MAGN2(m,v) DOT(m,v,v)
  23. #if _X86_
  24. #define SHADER __GLcontext.polygon.shader
  25. #define GET_HALF_AREA(gc, a, b, c)\
  26. \
  27. __asm{ mov eax, a };\
  28. __asm{ mov ecx, c };\
  29. __asm{ mov ebx, b };\
  30. __asm{ mov edx, gc };\
  31. __asm{ fld DWORD PTR [OFFSET(__GLvertex.window.x)][eax] };\
  32. __asm{ fsub DWORD PTR [OFFSET(__GLvertex.window.x)][ecx] /* dxAC */ };\
  33. __asm{ fld DWORD PTR [OFFSET(__GLvertex.window.y)][ebx] };\
  34. __asm{ fsub DWORD PTR [OFFSET(__GLvertex.window.y)][ecx] /* dyBC dxAC */ };\
  35. __asm{ fld DWORD PTR [OFFSET(__GLvertex.window.x)][ebx] };\
  36. __asm{ fsub DWORD PTR [OFFSET(__GLvertex.window.x)][ecx] /* dxBC dyBC dxAC */ };\
  37. __asm{ fld DWORD PTR [OFFSET(__GLvertex.window.y)][eax] };\
  38. __asm{ fsub DWORD PTR [OFFSET(__GLvertex.window.y)][ecx] /* dyAC dxBC dyBC dxAC */ };\
  39. __asm{ fxch ST(2) /* dyBC dxBC dyAC dxAC */ };\
  40. __asm{ fst DWORD PTR [OFFSET(SHADER.dyBC)][edx] };\
  41. __asm{ fmul ST, ST(3) /* dxACdyBC dxBC dyAC dxAC */ };\
  42. __asm{ fxch ST(2) /* dyAC dxBC dxACdyBC dxAC */ };\
  43. __asm{ fst DWORD PTR [OFFSET(SHADER.dyAC)][edx] };\
  44. __asm{ fmul ST, ST(1) /* dxBCdyAC dxBC dxACdyBC dxAC */};\
  45. __asm{ fxch ST(1) /* dxBC dxBCdyAC dxACdyBC dxAC */};\
  46. __asm{ fstp DWORD PTR [OFFSET(SHADER.dxBC)][edx] /* dxBCdyAC dxACdyBC dxAC */ };\
  47. __asm{ fsubp ST(1), ST /* +1*/ /* area dxAC */ };\
  48. __asm{ fxch ST(1) /* dxAC area */ };\
  49. __asm{ fstp DWORD PTR [OFFSET(SHADER.dxAC)][edx] /* area */ };\
  50. __asm{ fstp DWORD PTR [OFFSET(SHADER.area)][edx] /* +1*/ /* (empty) */ };
  51. #define STORE_AREA_PARAMS
  52. #else
  53. #define GET_HALF_AREA(gc, a, b, c)\
  54. /* Compute signed half-area of the triangle */ \
  55. dxAC = a->window.x - c->window.x; \
  56. dxBC = b->window.x - c->window.x; \
  57. dyAC = a->window.y - c->window.y; \
  58. dyBC = b->window.y - c->window.y; \
  59. gc->polygon.shader.area = dxAC * dyBC - dxBC * dyAC;
  60. #define STORE_AREA_PARAMS\
  61. gc->polygon.shader.dxAC = dxAC; \
  62. gc->polygon.shader.dxBC = dxBC; \
  63. gc->polygon.shader.dyAC = dyAC; \
  64. gc->polygon.shader.dyBC = dyBC;
  65. #endif
  66. #if 0
  67. #define ACCUM_MAT_CHANGE(dst,src) \
  68. if ((src)->dirtyBits & __GL_MATERIAL_AMBIENT) \
  69. (dst).ambient = (src)->ambient; \
  70. if ((src)->dirtyBits & __GL_MATERIAL_DIFFUSE) \
  71. (dst).diffuse = (src)->diffuse; \
  72. if ((src)->dirtyBits & __GL_MATERIAL_SPECULAR) \
  73. (dst).specular = (src)->specular; \
  74. if ((src)->dirtyBits & __GL_MATERIAL_EMISSIVE) \
  75. (dst).emissive = (src)->emissive; \
  76. if ((src)->dirtyBits & __GL_MATERIAL_SHININESS) \
  77. (dst).shininess = (src)->shininess; \
  78. if ((src)->dirtyBits & __GL_MATERIAL_COLORINDEXES) \
  79. { \
  80. (dst).cmapa = (src)->cmapa; \
  81. (dst).cmapd = (src)->cmapd; \
  82. (dst).cmaps = (src)->cmaps; \
  83. } \
  84. (dst).dirtyBits |= (src)->dirtyBits;
  85. #endif
  86. #define SORT_AND_CULL_FACE(a, b, c, face, ccw)\
  87. \
  88. /* \
  89. ** Sort vertices in y. Keep track if a reversal of the winding \
  90. ** occurs in direction (0 means no reversal, 1 means reversal). \
  91. ** Save old vertex pointers in case we end up not doing a fill. \
  92. */ \
  93. reversed = 0; \
  94. if (__GL_VERTEX_COMPARE(a->window.y, <, b->window.y)) { \
  95. if (__GL_VERTEX_COMPARE(b->window.y, <, c->window.y)) { \
  96. /* Already sorted */ \
  97. } else { \
  98. if (__GL_VERTEX_COMPARE(a->window.y, <, c->window.y)) { \
  99. temp=b; b=c; c=temp; \
  100. reversed = 1; \
  101. } else { \
  102. temp=a; a=c; c=b; b=temp; \
  103. } \
  104. } \
  105. } else { \
  106. if (__GL_VERTEX_COMPARE(b->window.y, <, c->window.y)) { \
  107. if (__GL_VERTEX_COMPARE(a->window.y, <, c->window.y)) { \
  108. temp=a; a=b; b=temp; \
  109. reversed = 1; \
  110. } else { \
  111. temp=a; a=b; b=c; c=temp; \
  112. } \
  113. } else { \
  114. temp=a; a=c; c=temp; \
  115. reversed = 1; \
  116. } \
  117. } \
  118. \
  119. GET_HALF_AREA(gc, a, b, c); \
  120. ccw = !__GL_FLOAT_LTZ(gc->polygon.shader.area); \
  121. \
  122. /* \
  123. ** Figure out if face is culled or not. The face check needs to be \
  124. ** based on the vertex winding before sorting. This code uses the \
  125. ** reversed flag to invert the sense of ccw - an xor accomplishes \
  126. ** this conversion without an if test. \
  127. ** \
  128. ** ccw reversed xor \
  129. ** --- -------- --- \
  130. ** 0 0 0 (remain !ccw) \
  131. ** 1 0 1 (remain ccw) \
  132. ** 0 1 1 (become ccw) \
  133. ** 1 1 0 (become cw) \
  134. */ \
  135. face = gc->polygon.face[ccw ^ reversed]; \
  136. if (face == gc->polygon.cullFace) { \
  137. /* Culled */ \
  138. return; \
  139. } \
  140. \
  141. STORE_AREA_PARAMS;
  142. //*************** Local functions *******************
  143. void SnapXLeft(__GLcontext *gc, __GLfloat xLeft, __GLfloat dxdyLeft);
  144. void SnapXRight(__GLshade *sh, __GLfloat xRight, __GLfloat dxdyRight);
  145. void InitLineParamsVan (__GLcontext *gc, __GLvertex *v0, __GLvertex *v1,
  146. __GLfloat invDelta);
  147. void InitLineParamsAccel (__GLcontext *gc, __GLvertex *v0, __GLvertex *v1,
  148. __GLfloat invDelta);
  149. static void SetInitialPhongParameters(__GLcontext *gc, __GLvertex *a,
  150. __GLcoord *an, __GLcolor *ac,
  151. __GLfloat aFog,
  152. __GLfloat dx, __GLfloat dy);
  153. void FASTCALL FillPhongSubTriangle(__GLcontext *gc, GLint iyBottom,
  154. GLint iyTop);
  155. void InitSpanInterpolationAccel (__GLcontext *gc);
  156. void InitSpanNEInterpolationVan (__GLcontext *gc);
  157. void InitSpanNInterpolationVan (__GLcontext *gc);
  158. void UpdateParamsAlongSpanAccel (__GLcontext *gc);
  159. void UpdateNAlongSpanVan (__GLcontext *gc);
  160. void UpdateNEAlongSpanVan (__GLcontext *gc);
  161. void ComputeRGBColorVanZippy (__GLcontext *gc, __GLcolor *outColor);
  162. void ComputeRGBColorVanFast (__GLcontext *gc, __GLcolor *outColor);
  163. void ComputeRGBColorVanSlow (__GLcontext *gc, __GLcolor *outColor);
  164. void ComputeRGBColorAccelZippy (__GLcontext *gc, __GLcolor *outColor);
  165. void ComputeRGBColorAccelFast (__GLcontext *gc, __GLcolor *outColor);
  166. // Not implemented yet. This is to accelerate Slow Lights
  167. void ComputeRGBColorAccelSlow (__GLcontext *gc, __GLcolor *outColor);
  168. // No Zippy versions for CI color
  169. // since there is no Color material for CI
  170. void ComputeCIColorVanFast (__GLcontext *gc, __GLcolor *outColor);
  171. void ComputeCIColorVanSlow (__GLcontext *gc, __GLcolor *outColor);
  172. void ComputeCIColorAccelFast (__GLcontext *gc, __GLcolor *outColor);
  173. void ComputePhongInvarientRGBColor (__GLcontext *gc);
  174. void __glCalcForwardDifferences( GLint w, __GLfloat p0, __GLfloat p1,
  175. __GLfloat p2, __GLfloat *d1, __GLfloat *d2 );
  176. #ifdef GL_WIN_specular_fog
  177. __GLfloat ComputeSpecValue (__GLcontext *gc, __GLvertex *vx);
  178. #endif //GL_WIN_specular_fog
  179. /********************* Code **************************************/
  180. #ifdef GL_WIN_specular_fog
  181. __GLfloat ComputeSpecValue (__GLcontext *gc, __GLvertex *vx)
  182. {
  183. __GLfloat nxi, nyi, nzi;
  184. __GLfloat zero;
  185. __GLlightSourcePerMaterialMachine *lspmm;
  186. __GLlightSourceMachine *lsm;
  187. __GLlightSourceState *lss;
  188. __GLmaterialMachine *msm;
  189. GLboolean eyeWIsZero, localViewer;
  190. static __GLcoord Pe = { 0, 0, 0, 1 };
  191. __GLcoord n, e;
  192. __GLfloat fog = 0;
  193. __GLfloat msm_threshold, msm_scale, *msm_specTable;
  194. zero = __glZero;
  195. n = vx->normal;
  196. e.x = vx->eyeX;
  197. e.y = vx->eyeY;
  198. e.z = vx->eyeZ;
  199. e.w = vx->eyeW;
  200. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  201. __glNormalize(&n.x, &n.x);
  202. msm = &gc->light.front;
  203. nxi = n.x;
  204. nyi = n.y;
  205. nzi = n.z;
  206. msm_scale = msm->scale;
  207. msm_threshold = msm->threshold;
  208. msm_specTable = msm->specTable;
  209. localViewer = gc->state.light.model.localViewer;
  210. eyeWIsZero = __GL_FLOAT_EQZ(vx->eyeW);
  211. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  212. {
  213. __GLfloat n1, n2;
  214. lss = lsm->state;
  215. lspmm = &lsm->front;
  216. if (lsm->slowPath || eyeWIsZero)
  217. {
  218. __GLcoord hHat, vPli, vPliHat, vPeHat;
  219. __GLfloat att, attSpot;
  220. __GLfloat hv[3];
  221. /* Compute unit h[i] */
  222. __glVecSub4(&vPli, &e, &lsm->position);
  223. __glNormalize(&vPliHat.x, &vPli.x);
  224. if (localViewer)
  225. {
  226. __glVecSub4(&vPeHat, &e, &Pe);
  227. __glNormalize(&vPeHat.x, &vPeHat.x);
  228. hv[0] = vPliHat.x + vPeHat.x;
  229. hv[1] = vPliHat.y + vPeHat.y;
  230. hv[2] = vPliHat.z + vPeHat.z;
  231. }
  232. else
  233. {
  234. hv[0] = vPliHat.x;
  235. hv[1] = vPliHat.y;
  236. hv[2] = vPliHat.z + __glOne;
  237. }
  238. __glNormalize(&hHat.x, hv);
  239. /* Compute attenuation */
  240. if (__GL_FLOAT_NEZ(lsm->position.w))
  241. {
  242. __GLfloat k0, k1, k2, dist;
  243. k0 = lsm->constantAttenuation;
  244. k1 = lsm->linearAttenuation;
  245. k2 = lsm->quadraticAttenuation;
  246. if (__GL_FLOAT_EQZ(k1) && __GL_FLOAT_EQZ(k2))
  247. {
  248. /* Use pre-computed 1/k0 */
  249. att = lsm->attenuation;
  250. }
  251. else
  252. {
  253. __GLfloat den;
  254. dist = __GL_SQRTF(vPli.x*vPli.x + vPli.y*vPli.y
  255. + vPli.z*vPli.z);
  256. den = k0 + k1 * dist + k2 * dist * dist;
  257. att = __GL_FLOAT_EQZ(den) ? __glOne : __glOne / den;
  258. }
  259. }
  260. else
  261. {
  262. att = __glOne;
  263. }
  264. /* Compute spot effect if light is a spot light */
  265. attSpot = att;
  266. if (lsm->isSpot)
  267. {
  268. __GLfloat dot, px, py, pz;
  269. px = -vPliHat.x;
  270. py = -vPliHat.y;
  271. pz = -vPliHat.z;
  272. dot = px * lsm->direction.x + py * lsm->direction.y
  273. + pz * lsm->direction.z;
  274. if ((dot >= lsm->threshold) && (dot >= lsm->cosCutOffAngle))
  275. {
  276. GLint ix = (GLint)((dot - lsm->threshold) * lsm->scale
  277. + __glHalf);
  278. if (ix < __GL_SPOT_LOOKUP_TABLE_SIZE)
  279. attSpot = att * lsm->spotTable[ix];
  280. }
  281. else
  282. {
  283. attSpot = zero;
  284. }
  285. }
  286. /* Add in remaining effect of light, if any */
  287. if (attSpot)
  288. {
  289. __GLfloat n1, n2;
  290. __GLcolor sum;
  291. n1 = nxi * vPliHat.x + nyi * vPliHat.y + nzi * vPliHat.z;
  292. if (__GL_FLOAT_GTZ(n1))
  293. {
  294. n2 = nxi * hHat.x + nyi * hHat.y + nzi * hHat.z;
  295. n2 -= msm_threshold;
  296. if (__GL_FLOAT_GEZ(n2))
  297. {
  298. __GLfloat fx = n2 * msm_scale + __glHalf;
  299. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  300. n2 = msm_specTable[(GLint)fx];
  301. else
  302. n2 = __glOne;
  303. fog += n2;
  304. }
  305. }
  306. }
  307. }
  308. else
  309. {
  310. __GLfloat n1, n2;
  311. /* Add in specular and diffuse effect of light, if any */
  312. n1 = nxi * lsm->unitVPpli.x + nyi * lsm->unitVPpli.y +
  313. nzi * lsm->unitVPpli.z;
  314. if (__GL_FLOAT_GTZ(n1))
  315. {
  316. n2= nxi * lsm->hHat.x + nyi * lsm->hHat.y + nzi * lsm->hHat.z;
  317. n2 -= msm_threshold;
  318. if (__GL_FLOAT_GEZ(n2))
  319. {
  320. __GLfloat fx = n2 * msm_scale + __glHalf;
  321. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  322. n2 = msm_specTable[(GLint)fx];
  323. else
  324. n2 = __glOne;
  325. fog += n2;
  326. }
  327. }
  328. }
  329. }
  330. fog = 1.0 - fog;
  331. if (__GL_FLOAT_LTZ (fog)) fog = __glZero;
  332. return fog;
  333. }
  334. #endif //GL_WIN_specular_fog
  335. static void AccumMatChange (__GLmatChange *dst, __GLmatChange *src)
  336. {
  337. if (src->dirtyBits & __GL_MATERIAL_AMBIENT)
  338. dst->ambient = src->ambient;
  339. if (src->dirtyBits & __GL_MATERIAL_DIFFUSE)
  340. dst->diffuse = src->diffuse;
  341. if (src->dirtyBits & __GL_MATERIAL_SPECULAR)
  342. dst->specular = src->specular;
  343. if (src->dirtyBits & __GL_MATERIAL_EMISSIVE)
  344. dst->emissive = src->emissive;
  345. if (src->dirtyBits & __GL_MATERIAL_SHININESS)
  346. dst->shininess = src->shininess;
  347. if (src->dirtyBits & __GL_MATERIAL_COLORINDEXES)
  348. {
  349. dst->cmapa = src->cmapa;
  350. dst->cmapd = src->cmapd;
  351. dst->cmaps = src->cmaps;
  352. }
  353. dst->dirtyBits |= src->dirtyBits;
  354. }
  355. // Propagate the valid Normals through the vertex buffer.
  356. //
  357. // IN: color, normal (front)
  358. // OUT: color, normal (front) (all vertices are updated)
  359. void FASTCALL PolyArrayPhongPropagateColorNormal(__GLcontext *gc,
  360. POLYARRAY *pa)
  361. {
  362. POLYDATA *pd;
  363. POLYDATA *pdLast;
  364. GLuint paNeeds;
  365. GLboolean doFrontColor, doBackColor;
  366. POLYMATERIAL *pm;
  367. __GLphongMaterialData *pmdata = NULL;
  368. paNeeds = gc->vertex.paNeeds;
  369. doFrontColor = paNeeds & PANEEDS_FRONT_COLOR;
  370. doBackColor = paNeeds & PANEEDS_BACK_COLOR;
  371. if (gc->polygon.shader.phong.flags & __GL_PHONG_NEED_EYE_XPOLATE)
  372. ASSERTOPENGL(pa->flags & POLYARRAY_EYE_PROCESSED,
  373. "Eye coordinate should be available now\n");
  374. // If color is not needed, fill in the colors field
  375. // with default.
  376. if (paNeeds & PANEEDS_SKIP_LIGHTING)
  377. {
  378. /////?????????!!!!!!!!!!! Look again!!!
  379. if (doFrontColor) (*gc->procs.paCalcColorSkip)(gc, pa, 0);
  380. if (doBackColor) (*gc->procs.paCalcColorSkip)(gc, pa, 1);
  381. return ;
  382. }
  383. pdLast = pa->pdNextVertex-1;
  384. // Check is there are any glMaterial calls that were made
  385. // immediately after glBegin, the ones made after the first
  386. // glVertex call are ignored.
  387. if (pa->flags & (POLYARRAY_MATERIAL_BACK | POLYARRAY_MATERIAL_BACK))
  388. {
  389. pm = GLTEB_CLTPOLYMATERIAL();
  390. //DbgPrint ("Has the costly material change\n");
  391. pmdata = (__GLphongMaterialData *)
  392. GCALLOC(gc, sizeof(__GLphongMaterialData));
  393. if (pmdata == NULL)
  394. {
  395. return;
  396. }
  397. pmdata->flags = 0;
  398. pmdata->matChange[__GL_PHONG_FRONT_FIRST].dirtyBits = 0;
  399. pmdata->matChange[__GL_PHONG_BACK_FIRST].dirtyBits = 0;
  400. pmdata->matChange[__GL_PHONG_FRONT_TRAIL].dirtyBits = 0;
  401. pmdata->matChange[__GL_PHONG_BACK_TRAIL].dirtyBits = 0;
  402. if (pa->pd0->flags & POLYARRAY_MATERIAL_BACK)
  403. {
  404. AccumMatChange (&(pmdata->matChange[__GL_PHONG_BACK_FIRST]),
  405. *(&pm->pdMaterial0[pa->pd0 - pa->pdBuffer0].front
  406. +1));
  407. pmdata->flags |= __GL_PHONG_BACK_FIRST_VALID;
  408. }
  409. if (pa->pd0->flags & POLYARRAY_MATERIAL_FRONT)
  410. {
  411. AccumMatChange (&(pmdata->matChange[__GL_PHONG_FRONT_FIRST]),
  412. *(&pm->pdMaterial0[pa->pd0 - pa->pdBuffer0].front));
  413. pmdata->flags |= __GL_PHONG_FRONT_FIRST_VALID;
  414. }
  415. // Accumulate the remaining material changes to be applied later
  416. for (pd = pa->pd0 + 1; pd <= pdLast; pd++)
  417. {
  418. if (pd->flags & POLYARRAY_MATERIAL_BACK)
  419. {
  420. AccumMatChange (&(pmdata->matChange[__GL_PHONG_BACK_TRAIL]),
  421. *(&pm->pdMaterial0[pd - pa->pdBuffer0].front+1));
  422. pmdata->flags |= __GL_PHONG_BACK_TRAIL_VALID;
  423. }
  424. if (pd->flags & POLYARRAY_MATERIAL_FRONT)
  425. {
  426. AccumMatChange (&(pmdata->matChange[__GL_PHONG_FRONT_TRAIL]),
  427. *(&pm->pdMaterial0[pd - pa->pdBuffer0].front));
  428. pmdata->flags |= __GL_PHONG_FRONT_TRAIL_VALID;
  429. }
  430. }
  431. pa->phong = pmdata;
  432. pa->flags |= POLYARRAY_PHONG_DATA_VALID;
  433. }
  434. for (pd = pa->pd0; pd <= pdLast; pd++)
  435. {
  436. if (gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE)
  437. {
  438. if (!(pd->flags & POLYDATA_COLOR_VALID))
  439. {
  440. // If color has not changed for this vertex,
  441. // use the previously computed color.
  442. ASSERTOPENGL(pd != pa->pd0, "no initial color\n");
  443. if (gc->modes.colorIndexMode)
  444. {
  445. pd->colors[0].r = (pd-1)->colors[0].r;
  446. }
  447. else
  448. {
  449. pd->colors[0].r = (pd-1)->colors[0].r;
  450. pd->colors[0].g = (pd-1)->colors[0].g;
  451. pd->colors[0].b = (pd-1)->colors[0].b;
  452. pd->colors[0].a = (pd-1)->colors[0].a;
  453. }
  454. pd->flags |= POLYDATA_COLOR_VALID;
  455. }
  456. else if (pa->flags & POLYARRAY_CLAMP_COLOR)
  457. {
  458. if (gc->modes.colorIndexMode)
  459. {
  460. __GL_CLAMP_CI(pd->colors[0].r, gc, pd->colors[0].r);
  461. }
  462. else
  463. {
  464. __GL_CLAMP_R(pd->colors[0].r, gc, pd->colors[0].r);
  465. __GL_CLAMP_G(pd->colors[0].g, gc, pd->colors[0].g);
  466. __GL_CLAMP_B(pd->colors[0].b, gc, pd->colors[0].b);
  467. __GL_CLAMP_A(pd->colors[0].a, gc, pd->colors[0].a);
  468. }
  469. }
  470. }
  471. if (!(pd->flags & POLYDATA_NORMAL_VALID))
  472. {
  473. // If the normal has not changed for this vertex,
  474. // use the previously computed normal.
  475. ASSERTOPENGL(pd != pa->pd0, "no initial normal\n");
  476. pd->normal = (pd-1)->normal;
  477. pd->flags |= POLYDATA_NORMAL_VALID;
  478. }
  479. else
  480. {
  481. if (gc->vertex.paNeeds & PANEEDS_NORMAL)
  482. {
  483. (*gc->mInv->xf3)(&pd->normal, &pd->normal.x, gc->mInv);
  484. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  485. __glNormalize(&pd->normal.x, &pd->normal.x);
  486. }
  487. }
  488. }
  489. gc->vertex.paNeeds &= ~PANEEDS_NORMAL;
  490. pa->flags &= ~POLYARRAY_MATERIAL_FRONT;
  491. pa->flags &= ~POLYARRAY_MATERIAL_BACK;
  492. pa->flags &= ~POLYARRAY_SAME_COLOR_DATA;
  493. }
  494. void FASTCALL
  495. __glRenderPhongTriangle(__GLcontext *gc, __GLvertex *a,
  496. __GLvertex *b, __GLvertex *c)
  497. {
  498. GLuint needs, modeFlags;
  499. GLint ccw, colorFace, reversed, face;
  500. __GLfloat dxAC, dxBC, dyAC, dyBC;
  501. __GLvertex *temp;
  502. #ifdef NO_RENDERING
  503. return;
  504. #endif
  505. //Assert that Lighting is on for Phong-shading to take place
  506. ASSERTOPENGL(gc->state.enables.general & __GL_LIGHTING_ENABLE,
  507. "No lighting. Should be smooth-shaded\n");
  508. SORT_AND_CULL_FACE(a, b, c, face, ccw);
  509. if (__GL_FLOAT_EQZ(gc->polygon.shader.area))
  510. return;
  511. /*
  512. ** Pick face to use for coloring
  513. */
  514. modeFlags = gc->polygon.shader.modeFlags;
  515. if (modeFlags & __GL_SHADE_TWOSIDED && face == __GL_BACKFACE)
  516. {
  517. gc->polygon.shader.phong.face = __GL_BACKFACE;
  518. }
  519. else
  520. {
  521. gc->polygon.shader.phong.face = __GL_FRONTFACE;
  522. }
  523. (*gc->procs.fillTriangle) (gc, a, b, c, (GLboolean) ccw);;
  524. }
  525. void FASTCALL
  526. __glFillPhongTriangle(__GLcontext *gc, __GLvertex *a, __GLvertex *b,
  527. __GLvertex *c, GLboolean ccw)
  528. {
  529. __GLfloat oneOverArea, t1, t2, t3, t4;
  530. __GLfloat dxAC, dxBC, dyAC, dyBC;
  531. __GLfloat aFog, bFog;
  532. __GLfloat dxAB, dyAB;
  533. __GLfloat dx, dy, dxdyLeft, dxdyRight;
  534. __GLcolor *ac, *bc;
  535. __GLcoord *an, *bn;
  536. __GLcoord ae, be, ce;
  537. GLint aIY, bIY, cIY;
  538. GLuint modeFlags;
  539. __GLfloat dxdyAC;
  540. __GLcoord dnAC, dnBC, *cn;
  541. __GLcoord deAC, deBC;
  542. __GLphongShader *phong = &gc->polygon.shader.phong;
  543. GLuint flags = 0, msm_colorMaterialChange;
  544. GLboolean needColor;
  545. //CHOP_ROUND_ON();
  546. FPU_SAVE_MODE ();
  547. FPU_CHOP_ON ();
  548. /* Pre-compute one over polygon area */
  549. __GL_FLOAT_BEGIN_DIVIDE(__glOne, gc->polygon.shader.area, &oneOverArea);
  550. modeFlags = gc->polygon.shader.modeFlags;
  551. if (gc->polygon.shader.phong.face == __GL_FRONTFACE)
  552. msm_colorMaterialChange = gc->light.front.colorMaterialChange;
  553. else
  554. msm_colorMaterialChange = gc->light.back.colorMaterialChange;
  555. if ((gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE) &&
  556. msm_colorMaterialChange && (modeFlags & __GL_SHADE_RGB))
  557. {
  558. flags |= __GL_PHONG_NEED_COLOR_XPOLATE;
  559. needColor = GL_TRUE;
  560. }
  561. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  562. //!!! Compute Invariant color if possible !!!!!!!!
  563. //!!! Use Otto's optimizations here !!!!!!!!
  564. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  565. if (((!(flags & __GL_PHONG_NEED_COLOR_XPOLATE) ||
  566. !(msm_colorMaterialChange & (__GL_MATERIAL_AMBIENT |
  567. __GL_MATERIAL_EMISSIVE))) &&
  568. (modeFlags & __GL_SHADE_RGB)) &&
  569. !(phong->flags & __GL_PHONG_NEED_EYE_XPOLATE))
  570. {
  571. ComputePhongInvarientRGBColor (gc);
  572. flags |= __GL_PHONG_INV_COLOR_VALID;
  573. }
  574. //Store the flags
  575. phong->flags |= flags;
  576. /* Fetch some stuff we are going to reuse */
  577. modeFlags = gc->polygon.shader.modeFlags;
  578. dxAC = gc->polygon.shader.dxAC;
  579. dxBC = gc->polygon.shader.dxBC;
  580. dyAC = gc->polygon.shader.dyAC;
  581. dyBC = gc->polygon.shader.dyBC;
  582. ac = a->color;
  583. bc = b->color;
  584. an = &(a->normal);
  585. bn = &(b->normal);
  586. ae.x = a->eyeX; ae.y = a->eyeY; ae.z = a->eyeZ; ae.w = a->eyeW;
  587. be.x = b->eyeX; be.y = b->eyeY; be.z = b->eyeZ; be.w = b->eyeW;
  588. /*
  589. ** Compute delta values for unit changes in x or y for each
  590. ** parameter.
  591. */
  592. __GL_FLOAT_SIMPLE_END_DIVIDE(oneOverArea);
  593. t1 = dyAC * oneOverArea;
  594. t2 = dyBC * oneOverArea;
  595. t3 = dxAC * oneOverArea;
  596. t4 = dxBC * oneOverArea;
  597. /* Normals */
  598. cn = &(c->normal);
  599. dnAC.x = an->x - cn->x;
  600. dnAC.y = an->y - cn->y;
  601. dnAC.z = an->z - cn->z;
  602. dnBC.x = bn->x - cn->x;
  603. dnBC.y = bn->y - cn->y;
  604. dnBC.z = bn->z - cn->z;
  605. gc->polygon.shader.phong.dndx.x = dnAC.x * t2 - dnBC.x * t1;
  606. gc->polygon.shader.phong.dndy.x = dnBC.x * t3 - dnAC.x * t4;
  607. gc->polygon.shader.phong.dndx.y = dnAC.y * t2 - dnBC.y * t1;
  608. gc->polygon.shader.phong.dndy.y = dnBC.y * t3 - dnAC.y * t4;
  609. gc->polygon.shader.phong.dndx.z = dnAC.z * t2 - dnBC.z * t1;
  610. gc->polygon.shader.phong.dndy.z = dnBC.z * t3 - dnAC.z * t4;
  611. if (phong->flags & __GL_PHONG_NEED_EYE_XPOLATE)
  612. {
  613. ce.x = c->eyeX; ce.y = c->eyeY; ce.z = c->eyeZ; ce.w = c->eyeW;
  614. deAC.x = ae.x - ce.x;
  615. deAC.y = ae.y - ce.y;
  616. deAC.z = ae.z - ce.z;
  617. deAC.w = ae.w - ce.w;
  618. deBC.x = be.x - ce.x;
  619. deBC.y = be.y - ce.y;
  620. deBC.z = be.z - ce.z;
  621. deBC.w = be.w - ce.w;
  622. gc->polygon.shader.phong.dedx.x = deAC.x * t2 - deBC.x * t1;
  623. gc->polygon.shader.phong.dedy.x = deBC.x * t3 - deAC.x * t4;
  624. gc->polygon.shader.phong.dedx.y = deAC.y * t2 - deBC.y * t1;
  625. gc->polygon.shader.phong.dedy.y = deBC.y * t3 - deAC.y * t4;
  626. gc->polygon.shader.phong.dedx.z = deAC.z * t2 - deBC.z * t1;
  627. gc->polygon.shader.phong.dedy.z = deBC.z * t3 - deAC.z * t4;
  628. gc->polygon.shader.phong.dedx.w = deAC.w * t2 - deBC.w * t1;
  629. gc->polygon.shader.phong.dedy.w = deBC.w * t3 - deAC.w * t4;
  630. }
  631. if (modeFlags & __GL_SHADE_RGB)
  632. {
  633. __GLfloat drAC, dgAC, dbAC, daAC;
  634. __GLfloat drBC, dgBC, dbBC, daBC;
  635. __GLcolor *cc;
  636. /* Colors */
  637. if (needColor)
  638. {
  639. cc = c->color;
  640. drAC = ac->r - cc->r;
  641. drBC = bc->r - cc->r;
  642. dgAC = ac->g - cc->g;
  643. dgBC = bc->g - cc->g;
  644. dbAC = ac->b - cc->b;
  645. dbBC = bc->b - cc->b;
  646. daAC = ac->a - cc->a;
  647. daBC = bc->a - cc->a;
  648. gc->polygon.shader.drdx = drAC * t2 - drBC * t1;
  649. gc->polygon.shader.drdy = drBC * t3 - drAC * t4;
  650. gc->polygon.shader.dgdx = dgAC * t2 - dgBC * t1;
  651. gc->polygon.shader.dgdy = dgBC * t3 - dgAC * t4;
  652. gc->polygon.shader.dbdx = dbAC * t2 - dbBC * t1;
  653. gc->polygon.shader.dbdy = dbBC * t3 - dbAC * t4;
  654. gc->polygon.shader.dadx = daAC * t2 - daBC * t1;
  655. gc->polygon.shader.dady = daBC * t3 - daAC * t4;
  656. }
  657. if (modeFlags & __GL_SHADE_TEXTURE)
  658. {
  659. __GLfloat awinv, bwinv, cwinv, scwinv, tcwinv, qwcwinv;
  660. __GLfloat dsAC, dsBC, dtAC, dtBC, dqwAC, dqwBC;
  661. awinv = a->window.w;
  662. bwinv = b->window.w;
  663. cwinv = c->window.w;
  664. scwinv = c->texture.x * cwinv;
  665. tcwinv = c->texture.y * cwinv;
  666. qwcwinv = c->texture.w * cwinv;
  667. dsAC = a->texture.x * awinv - scwinv;
  668. dsBC = b->texture.x * bwinv - scwinv;
  669. dtAC = a->texture.y * awinv - tcwinv;
  670. dtBC = b->texture.y * bwinv - tcwinv;
  671. dqwAC = a->texture.w * awinv - qwcwinv;
  672. dqwBC = b->texture.w * bwinv - qwcwinv;
  673. gc->polygon.shader.dsdx = dsAC * t2 - dsBC * t1;
  674. gc->polygon.shader.dsdy = dsBC * t3 - dsAC * t4;
  675. gc->polygon.shader.dtdx = dtAC * t2 - dtBC * t1;
  676. gc->polygon.shader.dtdy = dtBC * t3 - dtAC * t4;
  677. gc->polygon.shader.dqwdx = dqwAC * t2 - dqwBC * t1;
  678. gc->polygon.shader.dqwdy = dqwBC * t3 - dqwAC * t4;
  679. }
  680. }
  681. if (modeFlags & __GL_SHADE_DEPTH_ITER)
  682. {
  683. __GLfloat dzAC, dzBC;
  684. dzAC = a->window.z - c->window.z;
  685. dzBC = b->window.z - c->window.z;
  686. gc->polygon.shader.dzdxf = dzAC * t2 - dzBC * t1;
  687. gc->polygon.shader.dzdyf = dzBC * t3 - dzAC * t4;
  688. if(( gc->modes.depthBits == 16 ) &&
  689. ( gc->depthBuffer.scale <= (GLuint)0xffff )) {
  690. gc->polygon.shader.dzdx =
  691. FLT_TO_Z16_SCALE(gc->polygon.shader.dzdxf);
  692. }
  693. else {
  694. gc->polygon.shader.dzdx = FTOL(gc->polygon.shader.dzdxf);
  695. }
  696. }
  697. #ifdef GL_WIN_specular_fog
  698. if (gc->polygon.shader.modeFlags & __GL_SHADE_COMPUTE_FOG)
  699. {
  700. __GLfloat dfAC, dfBC, cFog;
  701. /* Use eyeZ for interpolation value */
  702. aFog = a->eyeZ;
  703. bFog = b->eyeZ;
  704. cFog = c->eyeZ;
  705. dfAC = aFog - cFog;
  706. dfBC = bFog - cFog;
  707. gc->polygon.shader.dfdx = dfAC * t2 - dfBC * t1;
  708. gc->polygon.shader.dfdy = dfBC * t3 - dfAC * t4;
  709. }
  710. else if (gc->polygon.shader.modeFlags & __GL_SHADE_INTERP_FOG)
  711. {
  712. __GLfloat dfAC, dfBC, cFog;
  713. aFog = bFog = cFog = 1.0f;
  714. if (gc->polygon.shader.modeFlags & __GL_SHADE_SPEC_FOG)
  715. {
  716. aFog = ComputeSpecValue (gc, a);
  717. bFog = ComputeSpecValue (gc, b);
  718. cFog = ComputeSpecValue (gc, c);
  719. }
  720. if (gc->polygon.shader.modeFlags & __GL_SHADE_SLOW_FOG)
  721. {
  722. aFog *= a->fog;
  723. bFog *= b->fog;
  724. cFog *= c->fog;
  725. }
  726. dfAC = aFog - cFog;
  727. dfBC = bFog - cFog;
  728. gc->polygon.shader.dfdx = dfAC * t2 - dfBC * t1;
  729. gc->polygon.shader.dfdy = dfBC * t3 - dfAC * t4;
  730. }
  731. #else //GL_WIN_specular_fog
  732. if (modeFlags & __GL_SHADE_COMPUTE_FOG)
  733. {
  734. __GLfloat dfAC, dfBC, cFog;
  735. /* Use eyeZ for interpolation value */
  736. aFog = a->eyeZ;
  737. bFog = b->eyeZ;
  738. cFog = c->eyeZ;
  739. dfAC = aFog - cFog;
  740. dfBC = bFog - cFog;
  741. gc->polygon.shader.dfdx = dfAC * t2 - dfBC * t1;
  742. gc->polygon.shader.dfdy = dfBC * t3 - dfAC * t4;
  743. }
  744. else if (modeFlags & __GL_SHADE_INTERP_FOG)
  745. {
  746. /* Use fog for interpolation value */
  747. aFog = a->fog;
  748. bFog = b->fog;
  749. cFog = c->fog;
  750. dfAC = aFog - cFog;
  751. dfBC = bFog - cFog;
  752. gc->polygon.shader.dfdx = dfAC * t2 - dfBC * t1;
  753. gc->polygon.shader.dfdy = dfBC * t3 - dfAC * t4;
  754. }
  755. #endif //GL_WIN_specular_fog
  756. __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(dxAC, dyAC, dxdyAC);
  757. /* Snap each y coordinate to its pixel center */
  758. aIY = __GL_VERTEX_FIXED_TO_INT(__GL_VERTEX_FLOAT_TO_FIXED(a->window.y)+
  759. __GL_VERTEX_FRAC_HALF);
  760. bIY = __GL_VERTEX_FIXED_TO_INT(__GL_VERTEX_FLOAT_TO_FIXED(b->window.y)+
  761. __GL_VERTEX_FRAC_HALF);
  762. cIY = __GL_VERTEX_FIXED_TO_INT(__GL_VERTEX_FLOAT_TO_FIXED(c->window.y)+
  763. __GL_VERTEX_FRAC_HALF);
  764. #ifdef __DBG_PRINT
  765. DbgPrint ("aIY=%d, bIY=%d, cIY=%d\n", aIY, bIY, cIY);
  766. #endif
  767. /*
  768. ** This algorithim always fills from bottom to top, left to right.
  769. ** Because of this, ccw triangles are inherently faster because
  770. ** the parameter values need not be recomputed.
  771. */
  772. dxAB = a->window.x - b->window.x;
  773. dyAB = a->window.y - b->window.y;
  774. if (ccw) {
  775. dy = (aIY + __glHalf) - a->window.y;
  776. __GL_FLOAT_SIMPLE_END_DIVIDE(dxdyAC);
  777. SnapXLeft(gc, a->window.x + dy*dxdyAC, dxdyAC);
  778. dx = (gc->polygon.shader.ixLeft + __glHalf) - a->window.x;
  779. SetInitialPhongParameters(gc, a, an, ac, aFog, dx, dy);
  780. if (aIY != bIY) {
  781. dxdyRight = dxAB / dyAB;
  782. SnapXRight(&gc->polygon.shader, a->window.x + dy*dxdyRight,
  783. dxdyRight);
  784. #ifdef __DBG_PRINT
  785. DbgPrint ("dxdyRight = %f\n", dxdyRight);
  786. #endif
  787. FillPhongSubTriangle(gc, aIY, bIY);
  788. }
  789. if (bIY != cIY) {
  790. dxdyRight = dxBC / dyBC;
  791. dy = (bIY + __glHalf) - b->window.y;
  792. SnapXRight(&gc->polygon.shader, b->window.x + dy*dxdyRight,
  793. dxdyRight);
  794. #ifdef __DBG_PRINT
  795. DbgPrint ("dxdyRight = %f\n", dxdyRight);
  796. #endif
  797. FillPhongSubTriangle(gc, bIY, cIY);
  798. }
  799. } else {
  800. dy = (aIY + __glHalf) - a->window.y;
  801. __GL_FLOAT_SIMPLE_END_DIVIDE(dxdyAC);
  802. SnapXRight(&gc->polygon.shader, a->window.x + dy*dxdyAC, dxdyAC);
  803. #ifdef __DBG_PRINT
  804. DbgPrint ("dxdyRight = %f\n", dxdyAC);
  805. #endif
  806. if (aIY != bIY) {
  807. dxdyLeft = dxAB / dyAB;
  808. SnapXLeft(gc, a->window.x + dy*dxdyLeft, dxdyLeft);
  809. dx = (gc->polygon.shader.ixLeft + __glHalf) - a->window.x;
  810. SetInitialPhongParameters(gc, a, an, ac, aFog, dx, dy);
  811. FillPhongSubTriangle(gc, aIY, bIY);
  812. }
  813. if (bIY != cIY) {
  814. dxdyLeft = dxBC / dyBC;
  815. dy = (bIY + __glHalf) - b->window.y;
  816. SnapXLeft(gc, b->window.x + dy*dxdyLeft, dxdyLeft);
  817. dx = (gc->polygon.shader.ixLeft + __glHalf) - b->window.x;
  818. SetInitialPhongParameters(gc, b, bn, bc, bFog, dx, dy);
  819. FillPhongSubTriangle(gc, bIY, cIY);
  820. }
  821. }
  822. FPU_RESTORE_MODE(); // CHOP_ROUND_OFF();
  823. }
  824. static void SetInitialPhongParameters(__GLcontext *gc, __GLvertex *a,
  825. __GLcoord *an, __GLcolor *ac,
  826. __GLfloat aFog, __GLfloat dx,
  827. __GLfloat dy)
  828. {
  829. GLint face = gc->polygon.shader.phong.face;
  830. __GLshade *sh = &gc->polygon.shader;
  831. __GLphongShader *phong = &gc->polygon.shader.phong;
  832. __GLfloat little = sh->dxLeftLittle;
  833. __GLfloat big = sh->dxLeftBig;
  834. GLuint modeFlags = sh->modeFlags;
  835. GLboolean needColor = (gc->polygon.shader.phong.flags &
  836. __GL_PHONG_NEED_COLOR_XPOLATE);
  837. #define bPolygonOffset \
  838. (gc->state.enables.general & __GL_POLYGON_OFFSET_FILL_ENABLE )
  839. /* Set parameters for the shader */
  840. phong->nCur.x = an->x + dx*phong->dndx.x + dy*phong->dndy.x;
  841. phong->nCur.y = an->y + dx*phong->dndx.y + dy*phong->dndy.y;
  842. phong->nCur.z = an->z + dx*phong->dndx.z + dy*phong->dndy.z;
  843. phong->nLittle.x = phong->dndy.x + little * phong->dndx.x;
  844. phong->nLittle.y = phong->dndy.y + little * phong->dndx.y;
  845. phong->nLittle.z = phong->dndy.z + little * phong->dndx.z;
  846. if (big > little)
  847. {
  848. phong->nBig.x = phong->nLittle.x + phong->dndx.x;
  849. phong->nBig.y = phong->nLittle.y + phong->dndx.y;
  850. phong->nBig.z = phong->nLittle.z + phong->dndx.z;
  851. }
  852. else
  853. {
  854. phong->nBig.x = phong->nLittle.x - phong->dndx.x;
  855. phong->nBig.y = phong->nLittle.y - phong->dndx.y;
  856. phong->nBig.z = phong->nLittle.z - phong->dndx.z;
  857. }
  858. if (phong->flags & __GL_PHONG_NEED_EYE_XPOLATE)
  859. {
  860. phong->eCur.x = a->eyeX + dx*phong->dedx.x + dy*phong->dedy.x;
  861. phong->eCur.y = a->eyeY + dx*phong->dedx.y + dy*phong->dedy.y;
  862. phong->eCur.z = a->eyeZ + dx*phong->dedx.z + dy*phong->dedy.z;
  863. phong->eCur.w = a->eyeW + dx*phong->dedx.w + dy*phong->dedy.w;
  864. phong->eLittle.x = phong->dedy.x + little * phong->dedx.x;
  865. phong->eLittle.y = phong->dedy.y + little * phong->dedx.y;
  866. phong->eLittle.z = phong->dedy.z + little * phong->dedx.z;
  867. phong->eLittle.w = phong->dedy.w + little * phong->dedx.w;
  868. if (big > little)
  869. {
  870. phong->eBig.x = phong->eLittle.x + phong->dedx.x;
  871. phong->eBig.y = phong->eLittle.y + phong->dedx.y;
  872. phong->eBig.z = phong->eLittle.z + phong->dedx.z;
  873. phong->eBig.w = phong->eLittle.w + phong->dedx.w;
  874. }
  875. else
  876. {
  877. phong->eBig.x = phong->eLittle.x - phong->dedx.x;
  878. phong->eBig.y = phong->eLittle.y - phong->dedx.y;
  879. phong->eBig.z = phong->eLittle.z - phong->dedx.z;
  880. phong->eBig.w = phong->eLittle.w - phong->dedx.w;
  881. }
  882. }
  883. if (big > little)
  884. {
  885. if (modeFlags & __GL_SHADE_RGB)
  886. {
  887. if (needColor)
  888. {
  889. sh->frag.color.r = ac->r + dx*sh->drdx + dy*sh->drdy;
  890. sh->rLittle = sh->drdy + little * sh->drdx;
  891. sh->rBig = sh->rLittle + sh->drdx;
  892. sh->frag.color.g = ac->g + dx*sh->dgdx + dy*sh->dgdy;
  893. sh->gLittle = sh->dgdy + little * sh->dgdx;
  894. sh->gBig = sh->gLittle + sh->dgdx;
  895. sh->frag.color.b = ac->b + dx*sh->dbdx + dy*sh->dbdy;
  896. sh->bLittle = sh->dbdy + little * sh->dbdx;
  897. sh->bBig = sh->bLittle + sh->dbdx;
  898. sh->frag.color.a = ac->a + dx*sh->dadx + dy*sh->dady;
  899. sh->aLittle = sh->dady + little * sh->dadx;
  900. sh->aBig =sh->aLittle + sh->dadx;
  901. }
  902. if (modeFlags & __GL_SHADE_TEXTURE)
  903. {
  904. __GLfloat oneOverW = a->window.w;
  905. sh->frag.s = a->texture.x * oneOverW + dx*sh->dsdx
  906. + dy*sh->dsdy;
  907. sh->sLittle = sh->dsdy + little * sh->dsdx;
  908. sh->sBig = sh->sLittle + sh->dsdx;
  909. sh->frag.t = a->texture.y * oneOverW + dx*sh->dtdx
  910. + dy*sh->dtdy;
  911. sh->tLittle = sh->dtdy + little * sh->dtdx;
  912. sh->tBig = sh->tLittle + sh->dtdx;
  913. sh->frag.qw = a->texture.w * oneOverW + dx*sh->dqwdx
  914. + dy*sh->dqwdy;
  915. sh->qwLittle = sh->dqwdy + little * sh->dqwdx;
  916. sh->qwBig = sh->qwLittle + sh->dqwdx;
  917. }
  918. }
  919. if (modeFlags & __GL_SHADE_DEPTH_ITER)
  920. {
  921. __GLfloat zLittle, zOffset;
  922. zOffset = bPolygonOffset ? __glPolygonOffsetZ(gc) : 0.0f;
  923. if (gc->modes.depthBits == 16)
  924. {
  925. sh->frag.z = (__GLzValue)
  926. FLT_TO_Z16_SCALE(a->window.z + dx*sh->dzdxf + dy*sh->dzdyf
  927. + zOffset );
  928. zLittle = sh->dzdyf + little * sh->dzdxf;
  929. sh->zLittle = FLT_TO_Z16_SCALE(zLittle);
  930. sh->zBig = FLT_TO_Z16_SCALE(zLittle + sh->dzdxf);
  931. }
  932. else
  933. {
  934. sh->frag.z = (__GLzValue)
  935. FTOL(a->window.z + dx*sh->dzdxf + dy*sh->dzdyf +
  936. zOffset );
  937. zLittle = sh->dzdyf + little * sh->dzdxf;
  938. sh->zLittle = FTOL(zLittle);
  939. sh->zBig = FTOL(zLittle + sh->dzdxf);
  940. }
  941. }
  942. if (modeFlags & (__GL_SHADE_COMPUTE_FOG | __GL_SHADE_INTERP_FOG))
  943. {
  944. sh->frag.f = aFog + dx*sh->dfdx + dy*sh->dfdy;
  945. sh->fLittle = sh->dfdy + little * sh->dfdx;
  946. sh->fBig = sh->fLittle + sh->dfdx;
  947. }
  948. }
  949. else
  950. {
  951. if (modeFlags & __GL_SHADE_RGB)
  952. {
  953. if (needColor)
  954. {
  955. sh->frag.color.r = ac->r + dx*sh->drdx + dy*sh->drdy;
  956. sh->rLittle = sh->drdy + little * sh->drdx;
  957. sh->rBig = sh->rLittle - sh->drdx;
  958. sh->frag.color.g = ac->g + dx*sh->dgdx + dy*sh->dgdy;
  959. sh->gLittle = sh->dgdy + little * sh->dgdx;
  960. sh->gBig = sh->gLittle - sh->dgdx;
  961. sh->frag.color.b = ac->b + dx*sh->dbdx + dy*sh->dbdy;
  962. sh->bLittle = sh->dbdy + little * sh->dbdx;
  963. sh->bBig = sh->bLittle - sh->dbdx;
  964. sh->frag.color.a = ac->a + dx*sh->dadx + dy*sh->dady;
  965. sh->aLittle = sh->dady + little * sh->dadx;
  966. sh->aBig =sh->aLittle - sh->dadx;
  967. }
  968. if (modeFlags & __GL_SHADE_TEXTURE)
  969. {
  970. __GLfloat oneOverW = a->window.w;
  971. sh->frag.s = a->texture.x * oneOverW + dx*sh->dsdx
  972. + dy*sh->dsdy;
  973. sh->sLittle = sh->dsdy + little * sh->dsdx;
  974. sh->sBig = sh->sLittle - sh->dsdx;
  975. sh->frag.t = a->texture.y * oneOverW + dx*sh->dtdx
  976. + dy*sh->dtdy;
  977. sh->tLittle = sh->dtdy + little * sh->dtdx;
  978. sh->tBig = sh->tLittle - sh->dtdx;
  979. sh->frag.qw = a->texture.w * oneOverW + dx*sh->dqwdx
  980. + dy*sh->dqwdy;
  981. sh->qwLittle = sh->dqwdy + little * sh->dqwdx;
  982. sh->qwBig = sh->qwLittle - sh->dqwdx;
  983. }
  984. }
  985. if (modeFlags & __GL_SHADE_DEPTH_ITER)
  986. {
  987. __GLfloat zLittle, zOffset;
  988. zOffset = bPolygonOffset ? __glPolygonOffsetZ(gc) : 0.0f;
  989. if(( gc->modes.depthBits == 16 ) &&
  990. ( gc->depthBuffer.scale <= (GLuint)0xffff ))
  991. {
  992. sh->frag.z = (__GLzValue)
  993. FLT_TO_Z16_SCALE(a->window.z + dx*sh->dzdxf + dy*sh->dzdyf
  994. + zOffset );
  995. zLittle = sh->dzdyf + little * sh->dzdxf;
  996. sh->zLittle = FLT_TO_Z16_SCALE(zLittle);
  997. sh->zBig = FLT_TO_Z16_SCALE(zLittle - sh->dzdxf);
  998. }
  999. else
  1000. {
  1001. sh->frag.z = (__GLzValue)
  1002. FTOL( a->window.z + dx*sh->dzdxf + dy*sh->dzdyf+ zOffset );
  1003. zLittle = sh->dzdyf + little * sh->dzdxf;
  1004. sh->zLittle = FTOL(zLittle);
  1005. sh->zBig = FTOL(zLittle - sh->dzdxf);
  1006. }
  1007. }
  1008. if (modeFlags & (__GL_SHADE_COMPUTE_FOG | __GL_SHADE_INTERP_FOG))
  1009. {
  1010. sh->frag.f = aFog + dx*sh->dfdx + dy*sh->dfdy;
  1011. sh->fLittle = sh->dfdy + little * sh->dfdx;
  1012. sh->fBig = sh->fLittle - sh->dfdx;
  1013. }
  1014. }
  1015. }
  1016. /* This routine sets gc->polygon.shader.cfb to gc->drawBuffer */
  1017. static void FASTCALL FillPhongSubTriangle(__GLcontext *gc, GLint iyBottom, GLint iyTop)
  1018. {
  1019. GLint ixLeft, ixRight;
  1020. GLint ixLeftFrac, ixRightFrac;
  1021. GLint dxLeftFrac, dxRightFrac;
  1022. GLint dxLeftLittle, dxRightLittle;
  1023. GLint dxLeftBig, dxRightBig;
  1024. GLint spanWidth, clipY0, clipY1;
  1025. GLuint modeFlags;
  1026. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1027. GLboolean needColor = (phong->flags & __GL_PHONG_NEED_COLOR_XPOLATE);
  1028. __GLstippleWord stackWords[__GL_MAX_STACK_STIPPLE_WORDS];
  1029. __GLstippleWord *words;
  1030. __GLcolor colors[__GL_MAX_STACKED_COLORS>>1];
  1031. __GLcolor fbcolors[__GL_MAX_STACKED_COLORS>>1];
  1032. __GLcolor *vColors, *vFbcolors;
  1033. int iMaxWidth, iDy, dxLeft, dxRight;
  1034. ixLeft = gc->polygon.shader.ixLeft;
  1035. dxLeft = (gc->polygon.shader.dxLeftBig < gc->polygon.shader.dxLeftLittle) ?
  1036. gc->polygon.shader.dxLeftBig : gc->polygon.shader.dxLeftLittle;
  1037. ixRight = gc->polygon.shader.ixRight;
  1038. dxRight = (gc->polygon.shader.dxRightBig > gc->polygon.shader.dxRightLittle) ?
  1039. gc->polygon.shader.dxRightBig : gc->polygon.shader.dxRightLittle;
  1040. iMaxWidth = ixRight - ixLeft;
  1041. iDy = iyTop - iyBottom - 1;
  1042. ixRight += dxRight * iDy;
  1043. ixLeft += dxLeft * iDy;
  1044. iMaxWidth = (iMaxWidth < (ixRight - ixLeft)) ? ixRight - ixLeft :
  1045. iMaxWidth;
  1046. if (iMaxWidth > __GL_MAX_STACK_STIPPLE_BITS)
  1047. {
  1048. words = gcTempAlloc(gc, (iMaxWidth+__GL_STIPPLE_BITS-1)/8);
  1049. if (words == NULL)
  1050. {
  1051. return;
  1052. }
  1053. }
  1054. else
  1055. {
  1056. words = stackWords;
  1057. }
  1058. if (iMaxWidth > (__GL_MAX_STACKED_COLORS>>1))
  1059. {
  1060. vColors = (__GLcolor *) gcTempAlloc(gc,
  1061. iMaxWidth * sizeof(__GLcolor));
  1062. if (NULL == vColors)
  1063. {
  1064. if (iMaxWidth > __GL_MAX_STACK_STIPPLE_BITS)
  1065. {
  1066. gcTempFree(gc, words);
  1067. }
  1068. return;
  1069. }
  1070. vFbcolors = (__GLcolor *) gcTempAlloc(gc,
  1071. iMaxWidth * sizeof(__GLcolor));
  1072. if (NULL == vFbcolors) {
  1073. if (iMaxWidth > __GL_MAX_STACK_STIPPLE_BITS)
  1074. {
  1075. gcTempFree(gc, words);
  1076. }
  1077. gcTempFree(gc, vColors);
  1078. return;
  1079. }
  1080. }
  1081. else
  1082. {
  1083. vColors = colors;
  1084. vFbcolors = fbcolors;
  1085. }
  1086. ixLeft = gc->polygon.shader.ixLeft;
  1087. ixLeftFrac = gc->polygon.shader.ixLeftFrac;
  1088. ixRight = gc->polygon.shader.ixRight;
  1089. ixRightFrac = gc->polygon.shader.ixRightFrac;
  1090. clipY0 = gc->transform.clipY0;
  1091. clipY1 = gc->transform.clipY1;
  1092. dxLeftFrac = gc->polygon.shader.dxLeftFrac;
  1093. dxLeftBig = gc->polygon.shader.dxLeftBig;
  1094. dxLeftLittle = gc->polygon.shader.dxLeftLittle;
  1095. dxRightFrac = gc->polygon.shader.dxRightFrac;
  1096. dxRightBig = gc->polygon.shader.dxRightBig;
  1097. dxRightLittle = gc->polygon.shader.dxRightLittle;
  1098. modeFlags = gc->polygon.shader.modeFlags;
  1099. gc->polygon.shader.colors = vColors;
  1100. gc->polygon.shader.fbcolors = vFbcolors;
  1101. gc->polygon.shader.stipplePat = words;
  1102. if (modeFlags & __GL_SHADE_STENCIL_TEST) {
  1103. gc->polygon.shader.sbuf =
  1104. __GL_STENCIL_ADDR(&gc->stencilBuffer, (__GLstencilCell*),
  1105. ixLeft, iyBottom);
  1106. }
  1107. if (modeFlags & __GL_SHADE_DEPTH_TEST) {
  1108. if( gc->modes.depthBits == 32 )
  1109. gc->polygon.shader.zbuf = (__GLzValue *)
  1110. __GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),
  1111. ixLeft, iyBottom);
  1112. else
  1113. gc->polygon.shader.zbuf = (__GLzValue *)
  1114. __GL_DEPTH_ADDR(&gc->depthBuffer, (__GLz16Value*),
  1115. ixLeft, iyBottom);
  1116. }
  1117. gc->polygon.shader.cfb = gc->drawBuffer;
  1118. while (iyBottom < iyTop)
  1119. {
  1120. spanWidth = ixRight - ixLeft;
  1121. /*
  1122. ** Only render spans that have non-zero width and which are
  1123. ** not scissored out vertically.
  1124. */
  1125. if ((spanWidth > 0) && (iyBottom >= clipY0) && (iyBottom < clipY1))
  1126. {
  1127. gc->polygon.shader.frag.x = ixLeft;
  1128. gc->polygon.shader.frag.y = iyBottom;
  1129. gc->polygon.shader.length = spanWidth;
  1130. /* Initialize Parameters to interpolate */
  1131. (*gc->procs.phong.InitSpanInterpolation) (gc);
  1132. (*gc->procs.span.processSpan)(gc);
  1133. }
  1134. /* Advance right edge fixed point, adjusting for carry */
  1135. ixRightFrac += dxRightFrac;
  1136. if (ixRightFrac < 0)
  1137. {
  1138. /* Carry/Borrow'd. Use large step */
  1139. ixRight += dxRightBig;
  1140. ixRightFrac &= ~0x80000000;
  1141. }
  1142. else
  1143. {
  1144. ixRight += dxRightLittle;
  1145. }
  1146. iyBottom++;
  1147. ixLeftFrac += dxLeftFrac;
  1148. if (ixLeftFrac < 0)
  1149. {
  1150. /* Carry/Borrow'd. Use large step */
  1151. ixLeft += dxLeftBig;
  1152. ixLeftFrac &= ~0x80000000;
  1153. phong->nCur.x += phong->nBig.x;
  1154. phong->nCur.y += phong->nBig.y;
  1155. phong->nCur.z += phong->nBig.z;
  1156. if (phong->flags & __GL_PHONG_NEED_EYE_XPOLATE)
  1157. {
  1158. phong->eCur.x += phong->eBig.x;
  1159. phong->eCur.y += phong->eBig.y;
  1160. phong->eCur.z += phong->eBig.z;
  1161. phong->eCur.w += phong->eBig.w;
  1162. }
  1163. if (modeFlags & __GL_SHADE_RGB)
  1164. {
  1165. if (needColor)
  1166. {
  1167. gc->polygon.shader.frag.color.r +=gc->polygon.shader.rBig;
  1168. gc->polygon.shader.frag.color.g +=gc->polygon.shader.gBig;
  1169. gc->polygon.shader.frag.color.b +=gc->polygon.shader.bBig;
  1170. gc->polygon.shader.frag.color.a +=gc->polygon.shader.aBig;
  1171. }
  1172. if (modeFlags & __GL_SHADE_TEXTURE)
  1173. {
  1174. gc->polygon.shader.frag.s += gc->polygon.shader.sBig;
  1175. gc->polygon.shader.frag.t += gc->polygon.shader.tBig;
  1176. gc->polygon.shader.frag.qw += gc->polygon.shader.qwBig;
  1177. }
  1178. }
  1179. if (modeFlags & __GL_SHADE_STENCIL_TEST) {
  1180. /* The implicit multiply is taken out of the loop */
  1181. gc->polygon.shader.sbuf = (__GLstencilCell*)
  1182. ((GLubyte*) gc->polygon.shader.sbuf
  1183. + gc->polygon.shader.sbufBig);
  1184. }
  1185. if (modeFlags & __GL_SHADE_DEPTH_ITER) {
  1186. gc->polygon.shader.frag.z += gc->polygon.shader.zBig;
  1187. }
  1188. if (modeFlags & __GL_SHADE_DEPTH_TEST) {
  1189. /* The implicit multiply is taken out of the loop */
  1190. gc->polygon.shader.zbuf = (__GLzValue*)
  1191. ((GLubyte*) gc->polygon.shader.zbuf
  1192. + gc->polygon.shader.zbufBig);
  1193. }
  1194. if (modeFlags & (__GL_SHADE_COMPUTE_FOG | __GL_SHADE_INTERP_FOG))
  1195. {
  1196. gc->polygon.shader.frag.f += gc->polygon.shader.fBig;
  1197. }
  1198. }
  1199. else
  1200. {
  1201. /* Use small step */
  1202. ixLeft += dxLeftLittle;
  1203. phong->nCur.x += phong->nLittle.x;
  1204. phong->nCur.y += phong->nLittle.y;
  1205. phong->nCur.z += phong->nLittle.z;
  1206. if (phong->flags & __GL_PHONG_NEED_EYE_XPOLATE)
  1207. {
  1208. phong->eCur.x += phong->eLittle.x;
  1209. phong->eCur.y += phong->eLittle.y;
  1210. phong->eCur.z += phong->eLittle.z;
  1211. phong->eCur.w += phong->eLittle.w;
  1212. }
  1213. if (modeFlags & __GL_SHADE_RGB)
  1214. {
  1215. if (needColor)
  1216. {
  1217. gc->polygon.shader.frag.color.r +=
  1218. gc->polygon.shader.rLittle;
  1219. gc->polygon.shader.frag.color.g +=
  1220. gc->polygon.shader.gLittle;
  1221. gc->polygon.shader.frag.color.b +=
  1222. gc->polygon.shader.bLittle;
  1223. gc->polygon.shader.frag.color.a +=
  1224. gc->polygon.shader.aLittle;
  1225. }
  1226. if (modeFlags & __GL_SHADE_TEXTURE) {
  1227. gc->polygon.shader.frag.s += gc->polygon.shader.sLittle;
  1228. gc->polygon.shader.frag.t += gc->polygon.shader.tLittle;
  1229. gc->polygon.shader.frag.qw += gc->polygon.shader.qwLittle;
  1230. }
  1231. }
  1232. if (modeFlags & __GL_SHADE_STENCIL_TEST) {
  1233. /* The implicit multiply is taken out of the loop */
  1234. gc->polygon.shader.sbuf = (__GLstencilCell*)
  1235. ((GLubyte*) gc->polygon.shader.sbuf
  1236. + gc->polygon.shader.sbufLittle);
  1237. }
  1238. if (modeFlags & __GL_SHADE_DEPTH_ITER) {
  1239. gc->polygon.shader.frag.z += gc->polygon.shader.zLittle;
  1240. }
  1241. if (modeFlags & __GL_SHADE_DEPTH_TEST) {
  1242. /* The implicit multiply is taken out of the loop */
  1243. gc->polygon.shader.zbuf = (__GLzValue*)
  1244. ((GLubyte*) gc->polygon.shader.zbuf
  1245. + gc->polygon.shader.zbufLittle);
  1246. }
  1247. if (modeFlags & (__GL_SHADE_COMPUTE_FOG | __GL_SHADE_INTERP_FOG))
  1248. {
  1249. gc->polygon.shader.frag.f += gc->polygon.shader.fLittle;
  1250. }
  1251. }
  1252. }
  1253. gc->polygon.shader.ixLeft = ixLeft;
  1254. gc->polygon.shader.ixLeftFrac = ixLeftFrac;
  1255. gc->polygon.shader.ixRight = ixRight;
  1256. gc->polygon.shader.ixRightFrac = ixRightFrac;
  1257. #ifdef NT
  1258. if (iMaxWidth > __GL_MAX_STACK_STIPPLE_BITS)
  1259. {
  1260. gcTempFree(gc, words);
  1261. }
  1262. if (iMaxWidth > (__GL_MAX_STACKED_COLORS>>1))
  1263. {
  1264. gcTempFree(gc, vColors);
  1265. gcTempFree(gc, vFbcolors);
  1266. }
  1267. #endif
  1268. }
  1269. static void SnapXLeft(__GLcontext *gc, __GLfloat xLeft, __GLfloat dxdyLeft)
  1270. {
  1271. GLint ixLeft, ixLeftFrac, lineBytes, elementSize, iLittle, iBig;
  1272. ASSERT_CHOP_ROUND();
  1273. ixLeft = __GL_VERTEX_FLOAT_TO_INT(xLeft);
  1274. /* Pre-add .5 to allow truncation in spanWidth calculation */
  1275. ixLeftFrac = __GL_VERTEX_PROMOTED_FRACTION(xLeft) + 0x40000000;
  1276. #ifdef __DBG_PRINT
  1277. DbgPrint ("dxdyLeft = %f\n", dxdyLeft);
  1278. #endif
  1279. gc->polygon.shader.ixLeft = ixLeft + (((GLuint) ixLeftFrac) >> 31);
  1280. gc->polygon.shader.ixLeftFrac = ixLeftFrac & ~0x80000000;
  1281. /* Compute big and little steps */
  1282. iLittle = FTOL(dxdyLeft);
  1283. gc->polygon.shader.dxLeftFrac = FLT_FRACTION(dxdyLeft - iLittle);
  1284. if (dxdyLeft < 0) {
  1285. iBig = iLittle - 1;
  1286. } else {
  1287. iBig = iLittle + 1;
  1288. }
  1289. if (gc->polygon.shader.modeFlags & __GL_SHADE_STENCIL_TEST) {
  1290. /*
  1291. ** Compute the big and little stencil buffer steps. We walk the
  1292. ** memory pointers for the stencil buffer along the edge of the
  1293. ** triangle as we walk the edge. This way we don't have to
  1294. ** recompute the buffer address as we go.
  1295. */
  1296. elementSize = gc->stencilBuffer.buf.elementSize;
  1297. lineBytes = elementSize * gc->stencilBuffer.buf.outerWidth;
  1298. gc->polygon.shader.sbufLittle = lineBytes + iLittle * elementSize;
  1299. gc->polygon.shader.sbufBig = lineBytes + iBig * elementSize;
  1300. }
  1301. if (gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_TEST) {
  1302. /*
  1303. ** Compute the big and little depth buffer steps. We walk the
  1304. ** memory pointers for the depth buffer along the edge of the
  1305. ** triangle as we walk the edge. This way we don't have to
  1306. ** recompute the buffer address as we go.
  1307. */
  1308. elementSize = gc->depthBuffer.buf.elementSize;
  1309. lineBytes = elementSize * gc->depthBuffer.buf.outerWidth;
  1310. gc->polygon.shader.zbufLittle = lineBytes + iLittle * elementSize;
  1311. gc->polygon.shader.zbufBig = lineBytes + iBig * elementSize;
  1312. }
  1313. gc->polygon.shader.dxLeftLittle = iLittle;
  1314. gc->polygon.shader.dxLeftBig = iBig;
  1315. }
  1316. static void SnapXRight(__GLshade *sh, __GLfloat xRight, __GLfloat dxdyRight)
  1317. {
  1318. GLint ixRight, ixRightFrac, iLittle, iBig;
  1319. ASSERT_CHOP_ROUND();
  1320. ixRight = __GL_VERTEX_FLOAT_TO_INT(xRight);
  1321. /* Pre-add .5 to allow truncation in spanWidth calculation */
  1322. ixRightFrac = __GL_VERTEX_PROMOTED_FRACTION(xRight) + 0x40000000;
  1323. sh->ixRight = ixRight + (((GLuint) ixRightFrac) >> 31);
  1324. sh->ixRightFrac = ixRightFrac & ~0x80000000;
  1325. /* Compute big and little steps */
  1326. iLittle = FTOL(dxdyRight);
  1327. sh->dxRightFrac = FLT_FRACTION(dxdyRight - iLittle);
  1328. if (dxdyRight < 0) {
  1329. iBig = iLittle - 1;
  1330. } else {
  1331. iBig = iLittle + 1;
  1332. }
  1333. sh->dxRightLittle = iLittle;
  1334. sh->dxRightBig = iBig;
  1335. }
  1336. void InitLineParamsVan (__GLcontext *gc, __GLvertex *v0, __GLvertex *v1,
  1337. __GLfloat invDelta)
  1338. {
  1339. __GLcoord *n0 = &(v0->normal);
  1340. __GLcoord *n1 = &(v1->normal);
  1341. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1342. GLuint msm_colorMaterialChange, flags=0;
  1343. GLuint modeFlags = gc->polygon.shader.modeFlags;
  1344. msm_colorMaterialChange = gc->light.front.colorMaterialChange;
  1345. phong->face = __GL_FRONTFACE;
  1346. if ((gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE) &&
  1347. msm_colorMaterialChange && (modeFlags & __GL_SHADE_RGB))
  1348. flags |= __GL_PHONG_NEED_COLOR_XPOLATE;
  1349. //Compute Invariant color if possible
  1350. if (((!(flags & __GL_PHONG_NEED_COLOR_XPOLATE) ||
  1351. !(msm_colorMaterialChange & (__GL_MATERIAL_AMBIENT |
  1352. __GL_MATERIAL_EMISSIVE))) &&
  1353. (modeFlags & __GL_SHADE_RGB)) &&
  1354. !(flags & __GL_PHONG_NEED_EYE_XPOLATE))
  1355. {
  1356. ComputePhongInvarientRGBColor (gc);
  1357. flags |= __GL_PHONG_INV_COLOR_VALID;
  1358. }
  1359. //Store the flags
  1360. gc->polygon.shader.phong.flags |= flags;
  1361. phong->dndx.x = (n1->x - n0->x) * invDelta;
  1362. phong->dndx.y = (n1->y - n0->y) * invDelta;
  1363. phong->dndx.z = (n1->z - n0->z) * invDelta;
  1364. phong->nTmp.x = n0->x;
  1365. phong->nTmp.y = n0->y;
  1366. phong->nTmp.z = n0->z;
  1367. if (gc->polygon.shader.phong.flags & __GL_PHONG_NEED_EYE_XPOLATE)
  1368. {
  1369. phong->dedx.x = (v1->eyeX - v0->eyeX) * invDelta;
  1370. phong->dedx.y = (v1->eyeY - v0->eyeY) * invDelta;
  1371. phong->dedx.z = (v1->eyeZ - v0->eyeZ) * invDelta;
  1372. phong->eTmp.x = v0->eyeX;
  1373. phong->eTmp.y = v0->eyeY;
  1374. phong->eTmp.z = v0->eyeZ;
  1375. }
  1376. }
  1377. void InitLineParamsAccel (__GLcontext *gc, __GLvertex *v0, __GLvertex *v1,
  1378. __GLfloat invDelta)
  1379. {
  1380. __GLcoord normal;
  1381. __GLcoord *n0 = &(v0->normal);
  1382. __GLcoord *n1 = &normal;
  1383. __GLcoord *n2 = &(v1->normal);
  1384. __GLlightSourceMachine *lsm;
  1385. GLuint msm_colorMaterialChange, flags = 0;
  1386. GLuint modeFlags = gc->polygon.shader.modeFlags;
  1387. __GLphongShader *phong = &gc->polygon.shader.phong;
  1388. GLint face = phong->face, curL, w;
  1389. msm_colorMaterialChange = gc->light.front.colorMaterialChange;
  1390. phong->face = __GL_FRONTFACE;
  1391. w = gc->line.options.numPixels;
  1392. if ((gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE) &&
  1393. msm_colorMaterialChange && (modeFlags & __GL_SHADE_RGB))
  1394. flags |= __GL_PHONG_NEED_COLOR_XPOLATE;
  1395. //Compute Invariant color if possible
  1396. if (((!(flags & __GL_PHONG_NEED_COLOR_XPOLATE) ||
  1397. !(msm_colorMaterialChange & (__GL_MATERIAL_AMBIENT |
  1398. __GL_MATERIAL_EMISSIVE))) &&
  1399. (modeFlags & __GL_SHADE_RGB)) &&
  1400. !(flags & __GL_PHONG_NEED_EYE_XPOLATE))
  1401. {
  1402. ComputePhongInvarientRGBColor (gc);
  1403. flags |= __GL_PHONG_INV_COLOR_VALID;
  1404. }
  1405. //Store the flags
  1406. gc->polygon.shader.phong.flags |= flags;
  1407. phong->dndx.x = (n2->x - n0->x) * invDelta;
  1408. phong->dndx.y = (n2->y - n0->y) * invDelta;
  1409. phong->dndx.x = (n2->z - n0->z) * invDelta;
  1410. normal.x = (n0->x + n2->x)/2.0f;
  1411. normal.y = (n0->y + n2->y)/2.0f;
  1412. normal.z = (n0->z + n2->z)/2.0f;
  1413. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  1414. __glNormalize(&normal.x, &normal.x);
  1415. for (lsm = gc->light.sources, curL = 0; lsm;
  1416. lsm = lsm->next, curL++)
  1417. {
  1418. __GLphongPerLightData *pld = &(phong->perLight[curL]);
  1419. __GLcoord *L = &(lsm->unitVPpli); // L is already normalized here
  1420. __GLcoord *H = &(lsm->hHat); // H is already normalized here
  1421. GLfloat d0, d1, d2;
  1422. /***** Diffuse *****/
  1423. DOT (d0,n0,L);
  1424. DOT (d1,n1,L);
  1425. DOT (d2,n2,L);
  1426. __glCalcForwardDifferences(w, d0, d1, d2, &pld->Ddel, &pld->Ddel2);
  1427. pld->Dcurr = d0;
  1428. /***** Specular ******/
  1429. DOT (d0,n0,H);
  1430. DOT (d1,n1,H);
  1431. DOT (d2,n2,H);
  1432. __glCalcForwardDifferences(w, d0, d1, d2, &pld->Sdel, &pld->Sdel2);
  1433. pld->Scurr = d0;
  1434. }
  1435. phong->numLights = curL;
  1436. }
  1437. void InitSpanNEInterpolationVan (__GLcontext *gc)
  1438. {
  1439. GLint i;
  1440. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1441. phong->nTmp = phong->nCur;
  1442. phong->eTmp = phong->eCur;
  1443. }
  1444. void InitSpanNInterpolationVan (__GLcontext *gc)
  1445. {
  1446. GLint i;
  1447. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1448. phong->nTmp = phong->nCur;
  1449. }
  1450. void InitSpanInterpolationAccel (__GLcontext *gc)
  1451. {
  1452. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1453. GLint face = phong->face;
  1454. __GLlightSourceMachine *lsm;
  1455. __GLcoord n0, n1, n2, dndx;
  1456. __GLcoord *N0 = &n0;
  1457. __GLcoord *N1 = &n1;
  1458. __GLcoord *N2 = &n2;
  1459. GLint curL, w, w2;
  1460. w = gc->polygon.shader.length;
  1461. w2 = w / 2;
  1462. if (face == __GL_FRONTFACE)
  1463. {
  1464. //msm = &gc->light.front;
  1465. n0.x = phong->nCur.x;
  1466. n0.y = phong->nCur.y;
  1467. n0.z = phong->nCur.z;
  1468. dndx.x = phong->dndx.x;
  1469. dndx.y = phong->dndx.y;
  1470. dndx.z = phong->dndx.z;
  1471. }
  1472. else
  1473. {
  1474. //msm = &gc->light.back;
  1475. n0.x = -phong->nCur.x;
  1476. n0.y = -phong->nCur.y;
  1477. n0.z = -phong->nCur.z;
  1478. dndx.x = -phong->dndx.x;
  1479. dndx.y = -phong->dndx.y;
  1480. dndx.z = -phong->dndx.z;
  1481. }
  1482. if (w > 2)
  1483. {
  1484. n2.x = n0.x + w*dndx.x;
  1485. n2.y = n0.y + w*dndx.y;
  1486. n2.z = n0.z + w*dndx.z;
  1487. n1.x = n0.x + w2*dndx.x;
  1488. n1.y = n0.y + w2*dndx.y;
  1489. n1.z = n0.z + w2*dndx.z;
  1490. }
  1491. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  1492. {
  1493. __glNormalize(&n0.x, &n0.x);
  1494. if (w > 2)
  1495. {
  1496. __glNormalize(&n1.x, &n1.x);
  1497. __glNormalize(&n2.x, &n2.x);
  1498. }
  1499. }
  1500. for (lsm = gc->light.sources, curL=0; lsm; lsm = lsm->next, curL++)
  1501. {
  1502. __GLphongPerLightData *pld = &(phong->perLight[curL]);
  1503. __GLcoord *L = &(lsm->unitVPpli); // L is already normalized here
  1504. __GLcoord *H = &(lsm->hHat); // H is already normalized here
  1505. GLfloat d0, d1, d2;
  1506. if (w > 2)
  1507. {
  1508. /***** Diffuse *****/
  1509. DOT (d0,N0,L);
  1510. DOT (d1,N1,L);
  1511. DOT (d2,N2,L);
  1512. __glCalcForwardDifferences(w, d0, d1, d2, &pld->Ddel,
  1513. &pld->Ddel2);
  1514. pld->Dcurr = d0;
  1515. /***** Specular ******/
  1516. DOT (d0, N0, H);
  1517. DOT (d1, N1, H);
  1518. DOT (d2, N2, H);
  1519. __glCalcForwardDifferences(w, d0, d1, d2, &pld->Sdel,
  1520. &pld->Sdel2);
  1521. pld->Scurr = d0;
  1522. }
  1523. else
  1524. {
  1525. /***** Diffuse *****/
  1526. DOT (d0,(&n0),L);
  1527. pld->Dcurr = d0;
  1528. pld->Ddel = 0.0;
  1529. pld->Ddel2 = 0.0;
  1530. /***** Specular ******/
  1531. DOT (d0,(&n0),H);
  1532. pld->Scurr = d0;
  1533. pld->Sdel = 0.0;
  1534. pld->Sdel2 = 0.0;
  1535. }
  1536. }
  1537. phong->numLights = curL;
  1538. }
  1539. void UpdateParamsAlongSpanAccel (__GLcontext *gc)
  1540. {
  1541. GLint i;
  1542. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1543. for (i=0; i<phong->numLights; i++)
  1544. {
  1545. __GLphongPerLightData *pld = &(phong->perLight[i]);
  1546. /* Diffuse */
  1547. pld->Dcurr += pld->Ddel;
  1548. pld->Ddel += pld->Ddel2;
  1549. /* Specular */
  1550. pld->Scurr += pld->Sdel;
  1551. pld->Sdel += pld->Sdel2;
  1552. }
  1553. }
  1554. void UpdateNAlongSpanVan (__GLcontext *gc)
  1555. {
  1556. GLint i;
  1557. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1558. phong->nTmp.x += phong->dndx.x;
  1559. phong->nTmp.y += phong->dndx.y;
  1560. phong->nTmp.z += phong->dndx.z;
  1561. }
  1562. void UpdateNEAlongSpanVan (__GLcontext *gc)
  1563. {
  1564. GLint i;
  1565. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1566. phong->nTmp.x += phong->dndx.x;
  1567. phong->nTmp.y += phong->dndx.y;
  1568. phong->nTmp.z += phong->dndx.z;
  1569. phong->eTmp.x += phong->dedx.x;
  1570. phong->eTmp.y += phong->dedx.y;
  1571. phong->eTmp.z += phong->dedx.z;
  1572. phong->eTmp.w += phong->dedx.w;
  1573. }
  1574. GLboolean FASTCALL __glPhongCISpan(__GLcontext *gc)
  1575. {
  1576. __GLcolor *cp, outColor;
  1577. __GLfloat r, drdx;
  1578. __GLcoord dndx;
  1579. GLint w;
  1580. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1581. GLboolean needColor = (gc->polygon.shader.phong.flags &
  1582. __GL_PHONG_NEED_COLOR_XPOLATE);
  1583. w = gc->polygon.shader.length;
  1584. cp = gc->polygon.shader.colors;
  1585. if (needColor)
  1586. {
  1587. phong->tmpColor.r = gc->polygon.shader.frag.color.r;
  1588. drdx = gc->polygon.shader.drdx;
  1589. }
  1590. while (--w >= 0)
  1591. {
  1592. /* Compute color using appropriate parameters */
  1593. (*gc->procs.phong.ComputeCIColor) (gc, &outColor);
  1594. cp->r = outColor.r;
  1595. /* Update parameters */
  1596. (*gc->procs.phong.UpdateAlongSpan) (gc);
  1597. if (needColor)
  1598. phong->tmpColor.r += drdx;
  1599. cp++;
  1600. }
  1601. return GL_FALSE;
  1602. }
  1603. GLboolean FASTCALL __glPhongRGBASpan (__GLcontext *gc)
  1604. {
  1605. __GLcolor *cp, dcdx, outColor;
  1606. __GLcoord dndx;
  1607. GLint w;
  1608. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1609. GLboolean needColor = (gc->polygon.shader.phong.flags &
  1610. __GL_PHONG_NEED_COLOR_XPOLATE);
  1611. w = gc->polygon.shader.length;
  1612. cp = gc->polygon.shader.colors;
  1613. if (needColor)
  1614. {
  1615. phong->tmpColor = gc->polygon.shader.frag.color;
  1616. dcdx.r = gc->polygon.shader.drdx;
  1617. dcdx.g = gc->polygon.shader.dgdx;
  1618. dcdx.b = gc->polygon.shader.dbdx;
  1619. dcdx.a = gc->polygon.shader.dadx;
  1620. }
  1621. while (--w >= 0)
  1622. {
  1623. /* Compute color using appropriate parameters */
  1624. (*gc->procs.phong.ComputeRGBColor) (gc, &outColor);
  1625. cp->r = outColor.r;
  1626. cp->g = outColor.g;
  1627. cp->b = outColor.b;
  1628. cp->a = outColor.a;
  1629. /* Update parameters */
  1630. (*gc->procs.phong.UpdateAlongSpan) (gc);
  1631. if (needColor)
  1632. {
  1633. phong->tmpColor.r += dcdx.r;
  1634. phong->tmpColor.g += dcdx.g;
  1635. phong->tmpColor.b += dcdx.b;
  1636. phong->tmpColor.a += dcdx.a;
  1637. }
  1638. cp++;
  1639. }
  1640. return GL_FALSE;
  1641. }
  1642. /*******************************************************************
  1643. * RGB, Use Normal, Fast-lights, no ColorMaterial*
  1644. *******************************************************************/
  1645. void ComputeRGBColorVanZippy (__GLcontext *gc, __GLcolor *outColor)
  1646. {
  1647. GLint face = gc->polygon.shader.phong.face;
  1648. __GLcoord n;
  1649. __GLfloat nxi, nyi, nzi;
  1650. __GLlightSourcePerMaterialMachine *lspmm;
  1651. __GLlightSourceMachine *lsm;
  1652. __GLlightSourceState *lss;
  1653. __GLcolor baseEmissiveAmbient;
  1654. __GLmaterialMachine *msm;
  1655. __GLfloat msm_alpha, msm_threshold, msm_scale, *msm_specTable;
  1656. GLuint numLights;
  1657. __GLfloat rsi=0.0, gsi=0.0, bsi=0.0;
  1658. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1659. ASSERTOPENGL (phong->flags & __GL_PHONG_INV_COLOR_VALID,
  1660. "Zippy, invarient color should have been computed\n");
  1661. ASSERTOPENGL (!(phong->flags & __GL_PHONG_NEED_COLOR_XPOLATE),
  1662. "Zippy, no need for color interpolation\n");
  1663. n = phong->nTmp;
  1664. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  1665. __glNormalize(&n.x, &n.x);
  1666. if (face == __GL_FRONTFACE)
  1667. {
  1668. msm = &gc->light.front;
  1669. nxi = n.x;
  1670. nyi = n.y;
  1671. nzi = n.z;
  1672. }
  1673. else
  1674. {
  1675. msm = &gc->light.back;
  1676. nxi = -n.x;
  1677. nyi = -n.y;
  1678. nzi = -n.z;
  1679. }
  1680. rsi = phong->invColor.r;
  1681. gsi = phong->invColor.g;
  1682. bsi = phong->invColor.b;
  1683. msm_alpha = msm->alpha;
  1684. msm_scale = msm->scale;
  1685. msm_threshold = msm->threshold;
  1686. msm_specTable = msm->specTable;
  1687. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  1688. {
  1689. __GLfloat n1, n2;
  1690. lspmm = &lsm->front + face;
  1691. /* Add in specular and diffuse effect of light, if any */
  1692. n1 = nxi * lsm->unitVPpli.x + nyi * lsm->unitVPpli.y +
  1693. nzi * lsm->unitVPpli.z;
  1694. if (__GL_FLOAT_GTZ(n1))
  1695. {
  1696. n2 = (nxi * lsm->hHat.x + nyi * lsm->hHat.y + nzi *
  1697. lsm->hHat.z) - msm_threshold;
  1698. if (__GL_FLOAT_GEZ(n2))
  1699. {
  1700. __GLfloat fx = n2 * msm_scale + __glHalf;
  1701. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  1702. n2 = msm_specTable[(GLint)fx];
  1703. else
  1704. n2 = __glOne;
  1705. rsi += n2 * lspmm->specular.r;
  1706. gsi += n2 * lspmm->specular.g;
  1707. bsi += n2 * lspmm->specular.b;
  1708. }
  1709. rsi += n1 * lspmm->diffuse.r;
  1710. gsi += n1 * lspmm->diffuse.g;
  1711. bsi += n1 * lspmm->diffuse.b;
  1712. }
  1713. }
  1714. __GL_CLAMP_R(outColor->r, gc, rsi);
  1715. __GL_CLAMP_G(outColor->g, gc, gsi);
  1716. __GL_CLAMP_B(outColor->b, gc, bsi);
  1717. outColor->a = msm_alpha;
  1718. }
  1719. /*******************************************************************
  1720. * RGB, Use Normal, Fast-lights, ColorMaterial *
  1721. *******************************************************************/
  1722. void ComputeRGBColorVanFast (__GLcontext *gc, __GLcolor *outColor)
  1723. {
  1724. GLint face = gc->polygon.shader.phong.face;
  1725. __GLfloat nxi, nyi, nzi;
  1726. __GLfloat zero;
  1727. __GLlightSourcePerMaterialMachine *lspmm;
  1728. __GLlightSourceMachine *lsm;
  1729. __GLlightSourceState *lss;
  1730. __GLfloat ri, gi, bi;
  1731. __GLfloat alpha;
  1732. __GLcolor emissiveAmbientI;
  1733. __GLcolor inColor;
  1734. __GLcolor diffuseSpecularI;
  1735. __GLcolor baseEmissiveAmbient;
  1736. __GLmaterialMachine *msm;
  1737. __GLcolor lm_ambient;
  1738. __GLfloat msm_alpha, msm_threshold, msm_scale, *msm_specTable;
  1739. GLuint msm_colorMaterialChange;
  1740. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1741. __GLcoord n;
  1742. zero = __glZero;
  1743. // Optimization: If no colors have been interpolated
  1744. // Use the Zippy function
  1745. if (!(phong->flags & __GL_PHONG_NEED_COLOR_XPOLATE))
  1746. ComputeRGBColorVanZippy (gc, outColor);
  1747. inColor = phong->tmpColor;
  1748. n = phong->nTmp;
  1749. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  1750. __glNormalize(&n.x, &n.x);
  1751. if (face == __GL_FRONTFACE)
  1752. {
  1753. msm = &gc->light.front;
  1754. nxi = n.x;
  1755. nyi = n.y;
  1756. nzi = n.z;
  1757. }
  1758. else
  1759. {
  1760. msm = &gc->light.back;
  1761. nxi = -n.x;
  1762. nyi = -n.y;
  1763. nzi = -n.z;
  1764. }
  1765. msm_scale = msm->scale;
  1766. msm_threshold = msm->threshold;
  1767. msm_specTable = msm->specTable;
  1768. msm_alpha = msm->alpha;
  1769. msm_colorMaterialChange = msm->colorMaterialChange;
  1770. // Save latest colors normalized to 0..1
  1771. ri = inColor.r * gc->oneOverRedVertexScale;
  1772. gi = inColor.g * gc->oneOverGreenVertexScale;
  1773. bi = inColor.b * gc->oneOverBlueVertexScale;
  1774. alpha = inColor.a;
  1775. // Compute invarient emissive and ambient components for this vertex.
  1776. if (phong->flags & __GL_PHONG_INV_COLOR_VALID)
  1777. {
  1778. emissiveAmbientI.r = phong->invColor.r;
  1779. emissiveAmbientI.g = phong->invColor.g;
  1780. emissiveAmbientI.b = phong->invColor.b;
  1781. }
  1782. else
  1783. {
  1784. lm_ambient.r = gc->state.light.model.ambient.r;
  1785. lm_ambient.g = gc->state.light.model.ambient.g;
  1786. lm_ambient.b = gc->state.light.model.ambient.b;
  1787. baseEmissiveAmbient.r = msm->paSceneColor.r;
  1788. baseEmissiveAmbient.g = msm->paSceneColor.g;
  1789. baseEmissiveAmbient.b = msm->paSceneColor.b;
  1790. if (msm_colorMaterialChange & __GL_MATERIAL_AMBIENT)
  1791. {
  1792. emissiveAmbientI.r = baseEmissiveAmbient.r
  1793. + ri * lm_ambient.r;
  1794. emissiveAmbientI.g = baseEmissiveAmbient.g
  1795. + gi * lm_ambient.g;
  1796. emissiveAmbientI.b = baseEmissiveAmbient.b
  1797. + bi * lm_ambient.b;
  1798. // Add per-light per-material ambient
  1799. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  1800. {
  1801. lss = lsm->state;
  1802. emissiveAmbientI.r += ri * lss->ambient.r;
  1803. emissiveAmbientI.g += gi * lss->ambient.g;
  1804. emissiveAmbientI.b += bi * lss->ambient.b;
  1805. }
  1806. }
  1807. else
  1808. {
  1809. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  1810. {
  1811. lspmm = &lsm->front + face;
  1812. baseEmissiveAmbient.r += lspmm->ambient.r;
  1813. baseEmissiveAmbient.g += lspmm->ambient.g;
  1814. baseEmissiveAmbient.b += lspmm->ambient.b;
  1815. }
  1816. emissiveAmbientI.r = baseEmissiveAmbient.r + inColor.r;
  1817. emissiveAmbientI.g = baseEmissiveAmbient.g + inColor.g;
  1818. emissiveAmbientI.b = baseEmissiveAmbient.b + inColor.b;
  1819. }
  1820. }
  1821. // Compute the diffuse and specular components for this vertex.
  1822. diffuseSpecularI.r = zero;
  1823. diffuseSpecularI.g = zero;
  1824. diffuseSpecularI.b = zero;
  1825. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  1826. {
  1827. __GLfloat n1, n2;
  1828. lss = lsm->state;
  1829. lspmm = &lsm->front + face;
  1830. /* Add in specular and diffuse effect of light, if any */
  1831. n1 = nxi * lsm->unitVPpli.x + nyi * lsm->unitVPpli.y +
  1832. nzi * lsm->unitVPpli.z;
  1833. if (__GL_FLOAT_GTZ(n1))
  1834. {
  1835. n2 = nxi * lsm->hHat.x + nyi * lsm->hHat.y + nzi * lsm->hHat.z;
  1836. n2 -= msm_threshold;
  1837. if (__GL_FLOAT_GEZ(n2))
  1838. {
  1839. __GLfloat fx = n2 * msm_scale + __glHalf;
  1840. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  1841. n2 = msm_specTable[(GLint)fx];
  1842. else
  1843. n2 = __glOne;
  1844. if (msm_colorMaterialChange & __GL_MATERIAL_SPECULAR)
  1845. {
  1846. /* Recompute per-light per-material cached specular */
  1847. diffuseSpecularI.r += n2 * ri * lss->specular.r;
  1848. diffuseSpecularI.g += n2 * gi * lss->specular.g;
  1849. diffuseSpecularI.b += n2 * bi * lss->specular.b;
  1850. }
  1851. else
  1852. {
  1853. diffuseSpecularI.r += n2 * lspmm->specular.r;
  1854. diffuseSpecularI.g += n2 * lspmm->specular.g;
  1855. diffuseSpecularI.b += n2 * lspmm->specular.b;
  1856. }
  1857. }
  1858. if (msm_colorMaterialChange & __GL_MATERIAL_DIFFUSE)
  1859. {
  1860. /* Recompute per-light per-material cached diffuse */
  1861. diffuseSpecularI.r += n1 * ri * lss->diffuse.r;
  1862. diffuseSpecularI.g += n1 * gi * lss->diffuse.g;
  1863. diffuseSpecularI.b += n1 * bi * lss->diffuse.b;
  1864. }
  1865. else
  1866. {
  1867. diffuseSpecularI.r += n1 * lspmm->diffuse.r;
  1868. diffuseSpecularI.g += n1 * lspmm->diffuse.g;
  1869. diffuseSpecularI.b += n1 * lspmm->diffuse.b;
  1870. }
  1871. }
  1872. }
  1873. __GL_CLAMP_R(outColor->r, gc, emissiveAmbientI.r + diffuseSpecularI.r);
  1874. __GL_CLAMP_G(outColor->g, gc, emissiveAmbientI.g + diffuseSpecularI.g);
  1875. __GL_CLAMP_B(outColor->b, gc, emissiveAmbientI.b + diffuseSpecularI.b);
  1876. if (msm_colorMaterialChange & __GL_MATERIAL_DIFFUSE)
  1877. {
  1878. __GL_CLAMP_A(outColor->a, gc, alpha);
  1879. }
  1880. else
  1881. outColor->a = msm_alpha;
  1882. }
  1883. /*******************************************************************
  1884. * RGB, Use Normal, Slow-lights, ColorMaterial *
  1885. *******************************************************************/
  1886. void ComputeRGBColorVanSlow (__GLcontext *gc, __GLcolor *outColor)
  1887. {
  1888. GLint face = gc->polygon.shader.phong.face;
  1889. __GLfloat nxi, nyi, nzi;
  1890. __GLfloat zero;
  1891. __GLlightSourcePerMaterialMachine *lspmm;
  1892. __GLlightSourceMachine *lsm;
  1893. __GLlightSourceState *lss;
  1894. __GLfloat ri, gi, bi;
  1895. __GLfloat alpha;
  1896. __GLfloat rsi, gsi, bsi;
  1897. __GLcolor sceneColorI;
  1898. __GLmaterialMachine *msm;
  1899. __GLcolor inColor;
  1900. __GLcolor lm_ambient;
  1901. __GLfloat msm_alpha, msm_threshold, msm_scale, *msm_specTable;
  1902. __GLcolor msm_paSceneColor;
  1903. GLuint msm_colorMaterialChange;
  1904. GLboolean eyeWIsZero, localViewer;
  1905. static __GLcoord Pe = { 0, 0, 0, 1 };
  1906. __GLcoord n;
  1907. __GLphongShader *phong = &(gc->polygon.shader.phong);
  1908. zero = __glZero;
  1909. inColor = phong->tmpColor;
  1910. n = phong->nTmp;
  1911. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  1912. __glNormalize(&n.x, &n.x);
  1913. if (face == __GL_FRONTFACE)
  1914. {
  1915. msm = &gc->light.front;
  1916. nxi = n.x;
  1917. nyi = n.y;
  1918. nzi = n.z;
  1919. }
  1920. else
  1921. {
  1922. msm = &gc->light.back;
  1923. nxi = -n.x;
  1924. nyi = -n.y;
  1925. nzi = -n.z;
  1926. }
  1927. lm_ambient.r = gc->state.light.model.ambient.r;
  1928. lm_ambient.g = gc->state.light.model.ambient.g;
  1929. lm_ambient.b = gc->state.light.model.ambient.b;
  1930. msm_scale = msm->scale;
  1931. msm_threshold = msm->threshold;
  1932. msm_specTable = msm->specTable;
  1933. msm_alpha = msm->alpha;
  1934. msm_colorMaterialChange = msm->colorMaterialChange;
  1935. msm_paSceneColor = msm->paSceneColor;
  1936. localViewer = gc->state.light.model.localViewer;
  1937. // Get invarient scene color if there is no ambient or emissive color
  1938. // material.
  1939. sceneColorI.r = msm_paSceneColor.r;
  1940. sceneColorI.g = msm_paSceneColor.g;
  1941. sceneColorI.b = msm_paSceneColor.b;
  1942. if (phong->flags & __GL_PHONG_NEED_EYE_XPOLATE)
  1943. {
  1944. // Save latest colors normalized to 0..1
  1945. ri = inColor.r * gc->oneOverRedVertexScale;
  1946. gi = inColor.g * gc->oneOverGreenVertexScale;
  1947. bi = inColor.b * gc->oneOverBlueVertexScale;
  1948. alpha = inColor.a;
  1949. // Compute scene color.
  1950. // If color has not changed, the previous sceneColorI values are
  1951. // used!
  1952. if (msm_colorMaterialChange & (__GL_MATERIAL_AMBIENT |
  1953. __GL_MATERIAL_EMISSIVE))
  1954. {
  1955. if (msm_colorMaterialChange & __GL_MATERIAL_AMBIENT)
  1956. {
  1957. sceneColorI.r = msm_paSceneColor.r + ri * lm_ambient.r;
  1958. sceneColorI.g = msm_paSceneColor.g + gi * lm_ambient.g;
  1959. sceneColorI.b = msm_paSceneColor.b + bi * lm_ambient.b;
  1960. }
  1961. else
  1962. {
  1963. sceneColorI.r = msm_paSceneColor.r + inColor.r;
  1964. sceneColorI.g = msm_paSceneColor.g + inColor.g;
  1965. sceneColorI.b = msm_paSceneColor.b + inColor.b;
  1966. }
  1967. }
  1968. }
  1969. // Compute the diffuse and specular components for this vertex.
  1970. rsi = sceneColorI.r;
  1971. gsi = sceneColorI.g;
  1972. bsi = sceneColorI.b;
  1973. eyeWIsZero = __GL_FLOAT_EQZ(phong->eTmp.w);
  1974. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  1975. {
  1976. __GLfloat n1, n2;
  1977. lss = lsm->state;
  1978. lspmm = &lsm->front + face;
  1979. if (lsm->slowPath || eyeWIsZero)
  1980. {
  1981. __GLcoord hHat, vPli, vPliHat, vPeHat;
  1982. __GLfloat att, attSpot;
  1983. __GLfloat hv[3];
  1984. /* Compute unit h[i] */
  1985. __glVecSub4(&vPli, &phong->eTmp, &lsm->position);
  1986. __glNormalize(&vPliHat.x, &vPli.x);
  1987. if (localViewer)
  1988. {
  1989. __glVecSub4(&vPeHat, &phong->eTmp, &Pe);
  1990. __glNormalize(&vPeHat.x, &vPeHat.x);
  1991. hv[0] = vPliHat.x + vPeHat.x;
  1992. hv[1] = vPliHat.y + vPeHat.y;
  1993. hv[2] = vPliHat.z + vPeHat.z;
  1994. }
  1995. else
  1996. {
  1997. hv[0] = vPliHat.x;
  1998. hv[1] = vPliHat.y;
  1999. hv[2] = vPliHat.z + __glOne;
  2000. }
  2001. __glNormalize(&hHat.x, hv);
  2002. /* Compute attenuation */
  2003. if (__GL_FLOAT_NEZ(lsm->position.w))
  2004. {
  2005. __GLfloat k0, k1, k2, dist;
  2006. k0 = lsm->constantAttenuation;
  2007. k1 = lsm->linearAttenuation;
  2008. k2 = lsm->quadraticAttenuation;
  2009. if (__GL_FLOAT_EQZ(k1) && __GL_FLOAT_EQZ(k2))
  2010. {
  2011. /* Use pre-computed 1/k0 */
  2012. att = lsm->attenuation;
  2013. }
  2014. else
  2015. {
  2016. __GLfloat den;
  2017. dist = __GL_SQRTF(vPli.x*vPli.x + vPli.y*vPli.y
  2018. + vPli.z*vPli.z);
  2019. den = k0 + k1 * dist + k2 * dist * dist;
  2020. att = __GL_FLOAT_EQZ(den) ? __glOne : __glOne / den;
  2021. }
  2022. }
  2023. else
  2024. {
  2025. att = __glOne;
  2026. }
  2027. /* Compute spot effect if light is a spot light */
  2028. attSpot = att;
  2029. if (lsm->isSpot)
  2030. {
  2031. __GLfloat dot, px, py, pz;
  2032. px = -vPliHat.x;
  2033. py = -vPliHat.y;
  2034. pz = -vPliHat.z;
  2035. dot = px * lsm->direction.x + py * lsm->direction.y
  2036. + pz * lsm->direction.z;
  2037. if ((dot >= lsm->threshold) && (dot >= lsm->cosCutOffAngle))
  2038. {
  2039. GLint ix = (GLint)((dot - lsm->threshold) * lsm->scale
  2040. + __glHalf);
  2041. if (ix < __GL_SPOT_LOOKUP_TABLE_SIZE)
  2042. attSpot = att * lsm->spotTable[ix];
  2043. }
  2044. else
  2045. {
  2046. attSpot = zero;
  2047. }
  2048. }
  2049. /* Add in remaining effect of light, if any */
  2050. if (attSpot)
  2051. {
  2052. __GLfloat n1, n2;
  2053. __GLcolor sum;
  2054. if (msm_colorMaterialChange & __GL_MATERIAL_AMBIENT)
  2055. {
  2056. sum.r = ri * lss->ambient.r;
  2057. sum.g = gi * lss->ambient.g;
  2058. sum.b = bi * lss->ambient.b;
  2059. }
  2060. else
  2061. {
  2062. sum.r = lspmm->ambient.r;
  2063. sum.g = lspmm->ambient.g;
  2064. sum.b = lspmm->ambient.b;
  2065. }
  2066. n1 = nxi * vPliHat.x + nyi * vPliHat.y + nzi * vPliHat.z;
  2067. if (__GL_FLOAT_GTZ(n1))
  2068. {
  2069. n2 = nxi * hHat.x + nyi * hHat.y + nzi * hHat.z;
  2070. n2 -= msm_threshold;
  2071. if (__GL_FLOAT_GEZ(n2))
  2072. {
  2073. __GLfloat fx = n2 * msm_scale + __glHalf;
  2074. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  2075. n2 = msm_specTable[(GLint)fx];
  2076. else
  2077. n2 = __glOne;
  2078. if (msm_colorMaterialChange & __GL_MATERIAL_SPECULAR)
  2079. {
  2080. /* Recompute per-light per-material cached specular */
  2081. sum.r += n2 * ri * lss->specular.r;
  2082. sum.g += n2 * gi * lss->specular.g;
  2083. sum.b += n2 * bi * lss->specular.b;
  2084. }
  2085. else
  2086. {
  2087. sum.r += n2 * lspmm->specular.r;
  2088. sum.g += n2 * lspmm->specular.g;
  2089. sum.b += n2 * lspmm->specular.b;
  2090. }
  2091. }
  2092. if (msm_colorMaterialChange & __GL_MATERIAL_DIFFUSE)
  2093. {
  2094. /* Recompute per-light per-material cached diffuse */
  2095. sum.r += n1 * ri * lss->diffuse.r;
  2096. sum.g += n1 * gi * lss->diffuse.g;
  2097. sum.b += n1 * bi * lss->diffuse.b;
  2098. }
  2099. else
  2100. {
  2101. sum.r += n1 * lspmm->diffuse.r;
  2102. sum.g += n1 * lspmm->diffuse.g;
  2103. sum.b += n1 * lspmm->diffuse.b;
  2104. }
  2105. }
  2106. rsi += attSpot * sum.r;
  2107. gsi += attSpot * sum.g;
  2108. bsi += attSpot * sum.b;
  2109. }
  2110. }
  2111. else
  2112. {
  2113. __GLfloat n1, n2;
  2114. if (msm_colorMaterialChange & __GL_MATERIAL_AMBIENT)
  2115. {
  2116. rsi += ri * lss->ambient.r;
  2117. gsi += gi * lss->ambient.g;
  2118. bsi += bi * lss->ambient.b;
  2119. }
  2120. else
  2121. {
  2122. rsi += lspmm->ambient.r;
  2123. gsi += lspmm->ambient.g;
  2124. bsi += lspmm->ambient.b;
  2125. }
  2126. /* Add in specular and diffuse effect of light, if any */
  2127. n1 = nxi * lsm->unitVPpli.x + nyi * lsm->unitVPpli.y +
  2128. nzi * lsm->unitVPpli.z;
  2129. if (__GL_FLOAT_GTZ(n1))
  2130. {
  2131. n2= nxi * lsm->hHat.x + nyi * lsm->hHat.y + nzi * lsm->hHat.z;
  2132. n2 -= msm_threshold;
  2133. if (__GL_FLOAT_GEZ(n2))
  2134. {
  2135. __GLfloat fx = n2 * msm_scale + __glHalf;
  2136. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  2137. n2 = msm_specTable[(GLint)fx];
  2138. else
  2139. n2 = __glOne;
  2140. if (msm_colorMaterialChange & __GL_MATERIAL_SPECULAR)
  2141. {
  2142. /* Recompute per-light per-material cached specular */
  2143. rsi += n2 * ri * lss->specular.r;
  2144. gsi += n2 * gi * lss->specular.g;
  2145. bsi += n2 * bi * lss->specular.b;
  2146. }
  2147. else
  2148. {
  2149. rsi += n2 * lspmm->specular.r;
  2150. gsi += n2 * lspmm->specular.g;
  2151. bsi += n2 * lspmm->specular.b;
  2152. }
  2153. }
  2154. if (msm_colorMaterialChange & __GL_MATERIAL_DIFFUSE)
  2155. {
  2156. /* Recompute per-light per-material cached diffuse */
  2157. rsi += n1 * ri * lss->diffuse.r;
  2158. gsi += n1 * gi * lss->diffuse.g;
  2159. bsi += n1 * bi * lss->diffuse.b;
  2160. }
  2161. else
  2162. {
  2163. rsi += n1 * lspmm->diffuse.r;
  2164. gsi += n1 * lspmm->diffuse.g;
  2165. bsi += n1 * lspmm->diffuse.b;
  2166. }
  2167. }
  2168. }
  2169. }
  2170. __GL_CLAMP_R(outColor->r, gc, rsi);
  2171. __GL_CLAMP_G(outColor->g, gc, gsi);
  2172. __GL_CLAMP_B(outColor->b, gc, bsi);
  2173. if (msm_colorMaterialChange & __GL_MATERIAL_DIFFUSE)
  2174. {
  2175. __GL_CLAMP_A(outColor->a, gc, alpha);
  2176. }
  2177. else
  2178. outColor->a = msm_alpha;
  2179. }
  2180. /*******************************************************************
  2181. * RGB, Use Dot, Fast-lights, no ColorMaterial *
  2182. *******************************************************************/
  2183. void ComputeRGBColorAccelZippy (__GLcontext *gc, __GLcolor *outColor)
  2184. {
  2185. GLint face = gc->polygon.shader.phong.face;
  2186. __GLlightSourcePerMaterialMachine *lspmm;
  2187. __GLlightSourceMachine *lsm;
  2188. __GLlightSourceState *lss;
  2189. __GLcolor baseEmissiveAmbient;
  2190. __GLmaterialMachine *msm;
  2191. __GLfloat msm_alpha, msm_threshold, msm_scale, *msm_specTable;
  2192. GLuint numLights;
  2193. __GLfloat rsi=0.0, gsi=0.0, bsi=0.0;
  2194. __GLphongShader *phong = &(gc->polygon.shader.phong);
  2195. GLint curL;
  2196. if (face == __GL_FRONTFACE)
  2197. msm = &gc->light.front;
  2198. else
  2199. msm = &gc->light.back;
  2200. ASSERTOPENGL (phong->flags & __GL_PHONG_INV_COLOR_VALID,
  2201. "Zippy, invarient color should have been computed\n");
  2202. ASSERTOPENGL (!(phong->flags & __GL_PHONG_NEED_COLOR_XPOLATE),
  2203. "Zippy, no need for color interpolation\n");
  2204. rsi = phong->invColor.r;
  2205. gsi = phong->invColor.g;
  2206. bsi = phong->invColor.b;
  2207. msm_alpha = msm->alpha;
  2208. msm_scale = msm->scale;
  2209. msm_threshold = msm->threshold;
  2210. msm_specTable = msm->specTable;
  2211. for (lsm = gc->light.sources, curL = 0; lsm; lsm = lsm->next, curL++)
  2212. {
  2213. __GLfloat n1, n2, x, y, x2, y2;
  2214. __GLphongPerLightData *pld = &(phong->perLight[curL]);
  2215. __GLfloat a, b, c, d, e, f, g, h, i;
  2216. /* Add in specular and diffuse effect of light, if any */
  2217. n1 = pld->Dcurr;
  2218. lspmm = &lsm->front + face;
  2219. if (__GL_FLOAT_GTZ(n1))
  2220. {
  2221. #ifdef __FASTEST
  2222. n2 = pld->Scurr - msm_threshold;
  2223. #endif //__FASTEST
  2224. #ifdef __SLOW
  2225. x = phong->tmp_pos.x; x2 = x*x;
  2226. y = phong->tmp_pos.y; y2 = y*y;
  2227. a = pld->A[0]; b = pld->A[1];
  2228. c = pld->A[2]; d = pld->A[3];
  2229. e = pld->A[4]; f = pld->A[5];
  2230. g = pld->A[6]; h = pld->A[7];
  2231. i = pld->A[8];
  2232. n2 = (a*x+b*y+c)/__GL_SQRTF(d*x2+e*x*y+f*y2+g*x+h*y+i);
  2233. #endif //__SLOW
  2234. #ifdef __FASTER
  2235. x = phong->tmp_pos.x; x2 = x*x;
  2236. y = phong->tmp_pos.y; y2 = y*y;
  2237. n2 = pld->S[5]*x2 + pld->S[4]*x*y + pld->S[3]*y2 + pld->S[2]*x +
  2238. pld->S[1]*y + pld->S[0];
  2239. #endif //__FASTER
  2240. //n2 -= msm_threshold;
  2241. if (__GL_FLOAT_GEZ(n2))
  2242. {
  2243. __GLfloat fx = n2 * msm_scale + __glHalf;
  2244. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  2245. n2 = msm_specTable[(GLint)fx];
  2246. else
  2247. n2 = __glOne;
  2248. rsi += n2 * lspmm->specular.r;
  2249. gsi += n2 * lspmm->specular.g;
  2250. bsi += n2 * lspmm->specular.b;
  2251. }
  2252. rsi += n1 * lspmm->diffuse.r;
  2253. gsi += n1 * lspmm->diffuse.g;
  2254. bsi += n1 * lspmm->diffuse.b;
  2255. }
  2256. }
  2257. __GL_CLAMP_R(outColor->r, gc, rsi);
  2258. __GL_CLAMP_G(outColor->g, gc, gsi);
  2259. __GL_CLAMP_B(outColor->b, gc, bsi);
  2260. outColor->a = msm_alpha;
  2261. }
  2262. /*******************************************************************
  2263. * RGB, Use Dot, Fast-lights, ColorMaterial *
  2264. *******************************************************************/
  2265. void ComputeRGBColorAccelFast (__GLcontext *gc, __GLcolor *outColor)
  2266. {
  2267. GLint face = gc->polygon.shader.phong.face;
  2268. __GLfloat zero;
  2269. __GLlightSourcePerMaterialMachine *lspmm;
  2270. __GLlightSourceMachine *lsm;
  2271. __GLlightSourceState *lss;
  2272. __GLfloat ri, gi, bi;
  2273. __GLfloat alpha;
  2274. __GLcolor emissiveAmbientI;
  2275. __GLcolor inColor;
  2276. __GLcolor diffuseSpecularI;
  2277. __GLcolor baseEmissiveAmbient;
  2278. __GLmaterialMachine *msm;
  2279. __GLcolor lm_ambient;
  2280. __GLfloat msm_alpha, msm_threshold, msm_scale, *msm_specTable;
  2281. GLuint msm_colorMaterialChange;
  2282. __GLphongShader *phong = &(gc->polygon.shader.phong);
  2283. GLint curL;
  2284. zero = __glZero;
  2285. if (face == __GL_FRONTFACE)
  2286. msm = &gc->light.front;
  2287. else
  2288. msm = &gc->light.back;
  2289. msm_colorMaterialChange = msm->colorMaterialChange;
  2290. ASSERTOPENGL (phong->flags & __GL_PHONG_NEED_COLOR_XPOLATE,
  2291. "Fast, need color interpolation\n");
  2292. #if 0
  2293. ASSERTOPENGL (!(gc->state.enables.general & __GL_NORMALIZE_ENABLE),
  2294. "Normalization should have been disabled\n");
  2295. #endif
  2296. inColor = phong->tmpColor;
  2297. msm_scale = msm->scale;
  2298. msm_threshold = msm->threshold;
  2299. msm_specTable = msm->specTable;
  2300. msm_alpha = msm->alpha;
  2301. // Save latest colors normalized to 0..1
  2302. ri = inColor.r * gc->oneOverRedVertexScale;
  2303. gi = inColor.g * gc->oneOverGreenVertexScale;
  2304. bi = inColor.b * gc->oneOverBlueVertexScale;
  2305. alpha = inColor.a;
  2306. // Compute invarient emissive and ambient components for this vertex.
  2307. if (phong->flags & __GL_PHONG_INV_COLOR_VALID)
  2308. {
  2309. emissiveAmbientI.r = phong->invColor.r;
  2310. emissiveAmbientI.g = phong->invColor.g;
  2311. emissiveAmbientI.b = phong->invColor.b;
  2312. }
  2313. else
  2314. {
  2315. lm_ambient.r = gc->state.light.model.ambient.r;
  2316. lm_ambient.g = gc->state.light.model.ambient.g;
  2317. lm_ambient.b = gc->state.light.model.ambient.b;
  2318. baseEmissiveAmbient.r = msm->paSceneColor.r;
  2319. baseEmissiveAmbient.g = msm->paSceneColor.g;
  2320. baseEmissiveAmbient.b = msm->paSceneColor.b;
  2321. if (msm_colorMaterialChange & __GL_MATERIAL_AMBIENT)
  2322. {
  2323. emissiveAmbientI.r = baseEmissiveAmbient.r
  2324. + ri * lm_ambient.r;
  2325. emissiveAmbientI.g = baseEmissiveAmbient.g
  2326. + gi * lm_ambient.g;
  2327. emissiveAmbientI.b = baseEmissiveAmbient.b
  2328. + bi * lm_ambient.b;
  2329. // Add per-light per-material ambient
  2330. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  2331. {
  2332. lss = lsm->state;
  2333. emissiveAmbientI.r += ri * lss->ambient.r;
  2334. emissiveAmbientI.g += gi * lss->ambient.g;
  2335. emissiveAmbientI.b += bi * lss->ambient.b;
  2336. }
  2337. }
  2338. else
  2339. {
  2340. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  2341. {
  2342. lspmm = &lsm->front + face;
  2343. baseEmissiveAmbient.r += lspmm->ambient.r;
  2344. baseEmissiveAmbient.g += lspmm->ambient.g;
  2345. baseEmissiveAmbient.b += lspmm->ambient.b;
  2346. }
  2347. emissiveAmbientI.r = baseEmissiveAmbient.r + inColor.r;
  2348. emissiveAmbientI.g = baseEmissiveAmbient.g + inColor.g;
  2349. emissiveAmbientI.b = baseEmissiveAmbient.b + inColor.b;
  2350. }
  2351. }
  2352. // Compute the diffuse and specular components for this vertex.
  2353. diffuseSpecularI.r = zero;
  2354. diffuseSpecularI.g = zero;
  2355. diffuseSpecularI.b = zero;
  2356. for (lsm = gc->light.sources, curL=0; lsm; lsm = lsm->next, curL++)
  2357. {
  2358. __GLfloat n1, n2;
  2359. __GLphongPerLightData *pld = &(phong->perLight[curL]);
  2360. lss = lsm->state;
  2361. lspmm = &lsm->front + face;
  2362. /* Add in specular and diffuse effect of light, if any */
  2363. n1 = pld->Dcurr;
  2364. if (__GL_FLOAT_GTZ(n1))
  2365. {
  2366. n2 = pld->Scurr - msm_threshold;
  2367. if (__GL_FLOAT_GEZ(n2))
  2368. {
  2369. __GLfloat fx = n2 * msm_scale + __glHalf;
  2370. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  2371. n2 = msm_specTable[(GLint)fx];
  2372. else
  2373. n2 = __glOne;
  2374. if (msm_colorMaterialChange & __GL_MATERIAL_SPECULAR)
  2375. {
  2376. /* Recompute per-light per-material cached specular */
  2377. diffuseSpecularI.r += n2 * ri * lss->specular.r;
  2378. diffuseSpecularI.g += n2 * gi * lss->specular.g;
  2379. diffuseSpecularI.b += n2 * bi * lss->specular.b;
  2380. }
  2381. else
  2382. {
  2383. diffuseSpecularI.r += n2 * lspmm->specular.r;
  2384. diffuseSpecularI.g += n2 * lspmm->specular.g;
  2385. diffuseSpecularI.b += n2 * lspmm->specular.b;
  2386. }
  2387. }
  2388. if (msm_colorMaterialChange & __GL_MATERIAL_DIFFUSE)
  2389. {
  2390. /* Recompute per-light per-material cached diffuse */
  2391. diffuseSpecularI.r += n1 * ri * lss->diffuse.r;
  2392. diffuseSpecularI.g += n1 * gi * lss->diffuse.g;
  2393. diffuseSpecularI.b += n1 * bi * lss->diffuse.b;
  2394. }
  2395. else
  2396. {
  2397. diffuseSpecularI.r += n1 * lspmm->diffuse.r;
  2398. diffuseSpecularI.g += n1 * lspmm->diffuse.g;
  2399. diffuseSpecularI.b += n1 * lspmm->diffuse.b;
  2400. }
  2401. }
  2402. }
  2403. __GL_CLAMP_R(outColor->r, gc, emissiveAmbientI.r + diffuseSpecularI.r);
  2404. __GL_CLAMP_G(outColor->g, gc, emissiveAmbientI.g + diffuseSpecularI.g);
  2405. __GL_CLAMP_B(outColor->b, gc, emissiveAmbientI.b + diffuseSpecularI.b);
  2406. if (msm_colorMaterialChange & __GL_MATERIAL_DIFFUSE)
  2407. {
  2408. __GL_CLAMP_A(outColor->a, gc, alpha);
  2409. }
  2410. else
  2411. outColor->a = msm_alpha;
  2412. }
  2413. /*******************************************************************
  2414. * CI, Vanilla, Fast-lights *
  2415. *******************************************************************/
  2416. void ComputeCIColorVanFast (__GLcontext *gc, __GLcolor *outColor)
  2417. {
  2418. GLint face = gc->polygon.shader.phong.face;
  2419. __GLfloat zero;
  2420. __GLcoord n;
  2421. __GLfloat nxi, nyi, nzi;
  2422. __GLlightSourcePerMaterialMachine *lspmm;
  2423. __GLlightSourceMachine *lsm;
  2424. __GLlightSourceState *lss;
  2425. __GLcolor baseEmissiveAmbient;
  2426. __GLmaterialMachine *msm;
  2427. __GLmaterialState *ms;
  2428. __GLfloat msm_threshold, msm_scale, *msm_specTable;
  2429. GLuint numLights;
  2430. __GLfloat ms_cmapa, ms_cmapd, ms_cmaps;
  2431. __GLfloat ci, si, di;
  2432. __GLphongShader *phong = &(gc->polygon.shader.phong);
  2433. GLfloat redMaxF;
  2434. GLint redMaxI;
  2435. zero = __glZero;
  2436. n = phong->nTmp;
  2437. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  2438. __glNormalize(&n.x, &n.x);
  2439. if (face == __GL_FRONTFACE)
  2440. {
  2441. ms = &gc->state.light.front;
  2442. msm = &gc->light.front;
  2443. nxi = n.x;
  2444. nyi = n.y;
  2445. nzi = n.z;
  2446. }
  2447. else
  2448. {
  2449. ms = &gc->state.light.back;
  2450. msm = &gc->light.back;
  2451. nxi = -n.x;
  2452. nyi = -n.y;
  2453. nzi = -n.z;
  2454. }
  2455. ASSERTOPENGL (!(phong->flags & __GL_PHONG_NEED_COLOR_XPOLATE),
  2456. "Zippy, no need for color interpolation\n");
  2457. msm_scale = msm->scale;
  2458. msm_threshold = msm->threshold;
  2459. msm_specTable = msm->specTable;
  2460. ms_cmapa = ms->cmapa;
  2461. ms_cmapd = ms->cmapd;
  2462. ms_cmaps = ms->cmaps;
  2463. redMaxF = (GLfloat) gc->frontBuffer.redMax;
  2464. redMaxI = (GLint) gc->frontBuffer.redMax;
  2465. si = zero;
  2466. di = zero;
  2467. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  2468. {
  2469. __GLfloat n1, n2;
  2470. lspmm = &lsm->front + face;
  2471. /* Add in specular and diffuse effect of light, if any */
  2472. n1 = nxi * lsm->unitVPpli.x + nyi * lsm->unitVPpli.y +
  2473. nzi * lsm->unitVPpli.z;
  2474. if (__GL_FLOAT_GTZ(n1))
  2475. {
  2476. n2 = (nxi * lsm->hHat.x + nyi * lsm->hHat.y + nzi *
  2477. lsm->hHat.z) - msm_threshold;
  2478. if (__GL_FLOAT_GEZ(n2))
  2479. {
  2480. __GLfloat fx = n2 * msm_scale + __glHalf;
  2481. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  2482. n2 = msm_specTable[(GLint)fx];
  2483. else
  2484. n2 = __glOne;
  2485. si += n2 * lsm->sli;
  2486. }
  2487. di += n1 * lsm->dli;
  2488. }
  2489. }
  2490. /* Compute final color */
  2491. if (si > __glOne)
  2492. si = __glOne;
  2493. ci = ms_cmapa + (__glOne - si) * di * (ms_cmapd - ms_cmapa)
  2494. + si * (ms_cmaps - ms_cmapa);
  2495. // need to mask color index before color clipping
  2496. if (ci > redMaxF)
  2497. {
  2498. GLfloat fraction;
  2499. GLint integer;
  2500. integer = (GLint) ci;
  2501. fraction = ci - (GLfloat) integer;
  2502. integer = integer & redMaxI;
  2503. ci = (GLfloat) integer + fraction;
  2504. }
  2505. else if (ci < 0)
  2506. {
  2507. GLfloat fraction;
  2508. GLint integer;
  2509. integer = (GLint) __GL_FLOORF(ci);
  2510. fraction = ci - (GLfloat) integer;
  2511. integer = integer & redMaxI;
  2512. ci = (GLfloat) integer + fraction;
  2513. }
  2514. outColor->r = ci;
  2515. }
  2516. /*******************************************************************
  2517. * CI, Vanilla, Slow-lights *
  2518. *******************************************************************/
  2519. void ComputeCIColorVanSlow (__GLcontext *gc, __GLcolor *outColor)
  2520. {
  2521. GLint face = gc->polygon.shader.phong.face;
  2522. __GLfloat nxi, nyi, nzi;
  2523. __GLfloat zero;
  2524. __GLlightSourceMachine *lsm;
  2525. __GLmaterialState *ms;
  2526. __GLmaterialMachine *msm;
  2527. __GLfloat msm_threshold, msm_scale, *msm_specTable;
  2528. __GLfloat ms_cmapa, ms_cmapd, ms_cmaps;
  2529. __GLfloat ci, si, di;
  2530. GLfloat redMaxF;
  2531. GLint redMaxI;
  2532. GLboolean eyeWIsZero, localViewer;
  2533. static __GLcoord Pe = { 0, 0, 0, 1 };
  2534. __GLphongShader *phong = &(gc->polygon.shader.phong);
  2535. __GLcoord n;
  2536. zero = __glZero;
  2537. n = phong->nTmp;
  2538. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  2539. __glNormalize(&n.x, &n.x);
  2540. if (face == __GL_FRONTFACE)
  2541. {
  2542. ms = &gc->state.light.front;
  2543. msm = &gc->light.front;
  2544. nxi = n.x;
  2545. nyi = n.y;
  2546. nzi = n.z;
  2547. }
  2548. else
  2549. {
  2550. ms = &gc->state.light.back;
  2551. msm = &gc->light.back;
  2552. nxi = -n.x;
  2553. nyi = -n.y;
  2554. nzi = -n.z;
  2555. }
  2556. msm_scale = msm->scale;
  2557. msm_threshold = msm->threshold;
  2558. msm_specTable = msm->specTable;
  2559. ms_cmapa = ms->cmapa;
  2560. ms_cmapd = ms->cmapd;
  2561. ms_cmaps = ms->cmaps;
  2562. localViewer = gc->state.light.model.localViewer;
  2563. redMaxF = (GLfloat) gc->frontBuffer.redMax;
  2564. redMaxI = (GLint) gc->frontBuffer.redMax;
  2565. si = zero;
  2566. di = zero;
  2567. eyeWIsZero = __GL_FLOAT_EQZ(phong->eTmp.w);
  2568. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  2569. {
  2570. if (lsm->slowPath || eyeWIsZero)
  2571. {
  2572. __GLfloat n1, n2, att, attSpot;
  2573. __GLcoord vPliHat, vPli, hHat, vPeHat;
  2574. __GLfloat hv[3];
  2575. /* Compute vPli, hi (normalized) */
  2576. __glVecSub4(&vPli, &phong->eTmp, &lsm->position);
  2577. __glNormalize(&vPliHat.x, &vPli.x);
  2578. if (localViewer)
  2579. {
  2580. __glVecSub4(&vPeHat, &phong->eTmp, &Pe);
  2581. __glNormalize(&vPeHat.x, &vPeHat.x);
  2582. hv[0] = vPliHat.x + vPeHat.x;
  2583. hv[1] = vPliHat.y + vPeHat.y;
  2584. hv[2] = vPliHat.z + vPeHat.z;
  2585. }
  2586. else
  2587. {
  2588. hv[0] = vPliHat.x;
  2589. hv[1] = vPliHat.y;
  2590. hv[2] = vPliHat.z + __glOne;
  2591. }
  2592. __glNormalize(&hHat.x, hv);
  2593. /* Compute attenuation */
  2594. if (__GL_FLOAT_NEZ(lsm->position.w))
  2595. {
  2596. __GLfloat k0, k1, k2, dist;
  2597. k0 = lsm->constantAttenuation;
  2598. k1 = lsm->linearAttenuation;
  2599. k2 = lsm->quadraticAttenuation;
  2600. if (__GL_FLOAT_EQZ(k1) && __GL_FLOAT_EQZ(k2))
  2601. {
  2602. /* Use pre-computed 1/k0 */
  2603. att = lsm->attenuation;
  2604. }
  2605. else
  2606. {
  2607. __GLfloat den;
  2608. dist = __GL_SQRTF(vPli.x*vPli.x + vPli.y*vPli.y
  2609. + vPli.z*vPli.z);
  2610. den = k0 + k1 * dist + k2 * dist * dist;
  2611. att = __GL_FLOAT_EQZ(den) ? __glOne : __glOne / den;
  2612. }
  2613. }
  2614. else
  2615. {
  2616. att = __glOne;
  2617. }
  2618. /* Compute spot effect if light is a spot light */
  2619. attSpot = att;
  2620. if (lsm->isSpot)
  2621. {
  2622. __GLfloat dot, px, py, pz;
  2623. px = -vPliHat.x;
  2624. py = -vPliHat.y;
  2625. pz = -vPliHat.z;
  2626. dot = px * lsm->direction.x + py * lsm->direction.y
  2627. + pz * lsm->direction.z;
  2628. if ((dot >= lsm->threshold) && (dot >= lsm->cosCutOffAngle))
  2629. {
  2630. GLint ix = (GLint)((dot - lsm->threshold) * lsm->scale
  2631. + __glHalf);
  2632. if (ix < __GL_SPOT_LOOKUP_TABLE_SIZE)
  2633. attSpot = att * lsm->spotTable[ix];
  2634. }
  2635. else
  2636. {
  2637. attSpot = zero;
  2638. }
  2639. }
  2640. /* Add in remaining effect of light, if any */
  2641. if (attSpot)
  2642. {
  2643. n1 = nxi * vPliHat.x + nyi * vPliHat.y + nzi * vPliHat.z;
  2644. if (__GL_FLOAT_GTZ(n1))
  2645. {
  2646. n2 = nxi * hHat.x + nyi * hHat.y + nzi * hHat.z;
  2647. n2 -= msm_threshold;
  2648. if (__GL_FLOAT_GEZ(n2))
  2649. {
  2650. __GLfloat fx = n2 * msm_scale + __glHalf;
  2651. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  2652. n2 = msm_specTable[(GLint)fx];
  2653. else
  2654. n2 = __glOne;
  2655. si += attSpot * n2 * lsm->sli;
  2656. }
  2657. di += attSpot * n1 * lsm->dli;
  2658. }
  2659. }
  2660. }
  2661. else
  2662. {
  2663. __GLfloat n1, n2;
  2664. /* Compute specular contribution */
  2665. n1 = nxi * lsm->unitVPpli.x + nyi * lsm->unitVPpli.y +
  2666. nzi * lsm->unitVPpli.z;
  2667. if (__GL_FLOAT_GTZ(n1))
  2668. {
  2669. n2= nxi * lsm->hHat.x + nyi * lsm->hHat.y + nzi * lsm->hHat.z;
  2670. n2 -= msm_threshold;
  2671. if (__GL_FLOAT_GEZ(n2))
  2672. {
  2673. __GLfloat fx = n2 * msm_scale + __glHalf;
  2674. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  2675. n2 = msm_specTable[(GLint)fx];
  2676. else
  2677. n2 = __glOne;
  2678. si += n2 * lsm->sli;
  2679. }
  2680. di += n1 * lsm->dli;
  2681. }
  2682. }
  2683. }
  2684. /* Compute final color */
  2685. if (si > __glOne)
  2686. si = __glOne;
  2687. ci = ms_cmapa + (__glOne - si) * di * (ms_cmapd - ms_cmapa)
  2688. + si * (ms_cmaps - ms_cmapa);
  2689. if (ci > ms_cmaps)
  2690. ci = ms_cmaps;
  2691. // need to mask color index before color clipping
  2692. if (ci > redMaxF)
  2693. {
  2694. GLfloat fraction;
  2695. GLint integer;
  2696. integer = (GLint) ci;
  2697. fraction = ci - (GLfloat) integer;
  2698. integer = integer & redMaxI;
  2699. ci = (GLfloat) integer + fraction;
  2700. }
  2701. else if (ci < 0)
  2702. {
  2703. GLfloat fraction;
  2704. GLint integer;
  2705. integer = (GLint) __GL_FLOORF(ci);
  2706. fraction = ci - (GLfloat) integer;
  2707. integer = integer & redMaxI;
  2708. ci = (GLfloat) integer + fraction;
  2709. }
  2710. outColor->r = ci;
  2711. }
  2712. /*******************************************************************
  2713. * CI, Fast-lights, Fast-path *
  2714. *******************************************************************/
  2715. void ComputeCIColorAccelFast (__GLcontext *gc, __GLcolor *outColor)
  2716. {
  2717. __GLfloat zero;
  2718. GLint face = gc->polygon.shader.phong.face;
  2719. __GLlightSourcePerMaterialMachine *lspmm;
  2720. __GLlightSourceMachine *lsm;
  2721. __GLlightSourceState *lss;
  2722. __GLcolor baseEmissiveAmbient;
  2723. __GLmaterialMachine *msm;
  2724. __GLmaterialState *ms;
  2725. __GLfloat msm_threshold, msm_scale, *msm_specTable;
  2726. GLuint numLights;
  2727. __GLfloat ms_cmapa, ms_cmapd, ms_cmaps;
  2728. __GLfloat ci, si, di;
  2729. __GLphongShader *phong = &(gc->polygon.shader.phong);
  2730. GLfloat redMaxF;
  2731. GLint redMaxI;
  2732. GLint curL;
  2733. zero = __glZero;
  2734. if (face == __GL_FRONTFACE)
  2735. {
  2736. ms = &gc->state.light.front;
  2737. msm = &gc->light.front;
  2738. }
  2739. else
  2740. {
  2741. ms = &gc->state.light.back;
  2742. msm = &gc->light.back;
  2743. }
  2744. ASSERTOPENGL (!(phong->flags & __GL_PHONG_NEED_COLOR_XPOLATE),
  2745. "Zippy, no need for color interpolation\n");
  2746. msm_scale = msm->scale;
  2747. msm_threshold = msm->threshold;
  2748. msm_specTable = msm->specTable;
  2749. ms_cmapa = ms->cmapa;
  2750. ms_cmapd = ms->cmapd;
  2751. ms_cmaps = ms->cmaps;
  2752. redMaxF = (GLfloat) gc->frontBuffer.redMax;
  2753. redMaxI = (GLint) gc->frontBuffer.redMax;
  2754. si = zero;
  2755. di = zero;
  2756. for (lsm = gc->light.sources, curL=0; lsm; lsm = lsm->next, curL++)
  2757. {
  2758. __GLfloat n1, n2;
  2759. __GLphongPerLightData *pld = &(phong->perLight[curL]);
  2760. lspmm = &lsm->front + face;
  2761. /* Add in specular and diffuse effect of light, if any */
  2762. n1 = pld->Dcurr;
  2763. if (__GL_FLOAT_GTZ(n1))
  2764. {
  2765. n2 = pld->Scurr - msm_threshold;
  2766. if (__GL_FLOAT_GEZ(n2))
  2767. {
  2768. __GLfloat fx = n2 * msm_scale + __glHalf;
  2769. if( fx < (__GLfloat)__GL_SPEC_LOOKUP_TABLE_SIZE )
  2770. n2 = msm_specTable[(GLint)fx];
  2771. else
  2772. n2 = __glOne;
  2773. si += n2 * lsm->sli;
  2774. }
  2775. di += n1 * lsm->dli;
  2776. }
  2777. }
  2778. /* Compute final color */
  2779. if (si > __glOne)
  2780. si = __glOne;
  2781. ci = ms_cmapa + (__glOne - si) * di * (ms_cmapd - ms_cmapa)
  2782. + si * (ms_cmaps - ms_cmapa);
  2783. // need to mask color index before color clipping
  2784. if (ci > redMaxF)
  2785. {
  2786. GLfloat fraction;
  2787. GLint integer;
  2788. integer = (GLint) ci;
  2789. fraction = ci - (GLfloat) integer;
  2790. integer = integer & redMaxI;
  2791. ci = (GLfloat) integer + fraction;
  2792. }
  2793. else if (ci < 0)
  2794. {
  2795. GLfloat fraction;
  2796. GLint integer;
  2797. integer = (GLint) __GL_FLOORF(ci);
  2798. fraction = ci - (GLfloat) integer;
  2799. integer = integer & redMaxI;
  2800. ci = (GLfloat) integer + fraction;
  2801. }
  2802. outColor->r = ci;
  2803. }
  2804. void ComputePhongInvarientRGBColor (__GLcontext *gc)
  2805. {
  2806. GLint face = gc->polygon.shader.phong.face;
  2807. __GLlightSourcePerMaterialMachine *lspmm;
  2808. __GLlightSourceMachine *lsm;
  2809. __GLlightSourceState *lss;
  2810. __GLmaterialMachine *msm;
  2811. __GLfloat msm_alpha;
  2812. __GLfloat rsi, gsi, bsi;
  2813. __GLphongShader *phong = &(gc->polygon.shader.phong);
  2814. if (face == __GL_FRONTFACE)
  2815. msm = &gc->light.front;
  2816. else
  2817. msm = &gc->light.back;
  2818. // Compute invarient emissive and ambient components for this vertex.
  2819. rsi = msm->paSceneColor.r;
  2820. gsi = msm->paSceneColor.g;
  2821. bsi = msm->paSceneColor.b;
  2822. // add invarient per-light per-material cached ambient
  2823. for (lsm = gc->light.sources; lsm; lsm = lsm->next)
  2824. {
  2825. lspmm = &lsm->front + face;
  2826. rsi += lspmm->ambient.r;
  2827. gsi += lspmm->ambient.g;
  2828. bsi += lspmm->ambient.b;
  2829. }
  2830. phong->invColor.r = rsi;
  2831. phong->invColor.g = gsi;
  2832. phong->invColor.b = bsi;
  2833. }
  2834. void FASTCALL __glGenericPickPhongProcs(__GLcontext *gc)
  2835. {
  2836. __GLlightSourceMachine *lsm;
  2837. GLboolean anySlow = GL_FALSE;
  2838. GLboolean colorMaterial = (gc->state.enables.general &
  2839. __GL_COLOR_MATERIAL_ENABLE);
  2840. GLboolean rgb_mode = (gc->polygon.shader.modeFlags & __GL_SHADE_RGB);
  2841. GLboolean normalize = (gc->state.enables.general & __GL_NORMALIZE_ENABLE);
  2842. GLboolean doVanilla = GL_FALSE;
  2843. gc->polygon.shader.phong.flags = 0;
  2844. for (lsm = gc->light.sources; lsm; lsm = lsm->next) {
  2845. if (lsm->slowPath) {
  2846. anySlow = GL_TRUE;
  2847. // Assuming here that anySlow means need Eye XPolate
  2848. gc->polygon.shader.phong.flags |= __GL_PHONG_NEED_EYE_XPOLATE;
  2849. break;
  2850. }
  2851. }
  2852. doVanilla = (!(gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  2853. || (anySlow)
  2854. || (gc->state.enables.general & __GL_POLYGON_SMOOTH_ENABLE)
  2855. || (gc->state.enables.general & __GL_LINE_SMOOTH_ENABLE)
  2856. );
  2857. if ((gc->state.hints.phong == GL_NICEST) || doVanilla)
  2858. {
  2859. gc->procs.phong.InitLineParams = InitLineParamsVan;
  2860. if (anySlow)
  2861. {
  2862. gc->procs.phong.InitSpanInterpolation = InitSpanNEInterpolationVan;
  2863. gc->procs.phong.UpdateAlongSpan = UpdateNEAlongSpanVan;
  2864. gc->procs.phong.ComputeRGBColor = ComputeRGBColorVanSlow;
  2865. gc->procs.phong.ComputeCIColor = ComputeCIColorVanSlow;
  2866. }
  2867. else
  2868. {
  2869. gc->procs.phong.InitSpanInterpolation = InitSpanNInterpolationVan;
  2870. gc->procs.phong.UpdateAlongSpan = UpdateNAlongSpanVan;
  2871. gc->procs.phong.ComputeCIColor = ComputeCIColorVanFast;
  2872. if (colorMaterial)
  2873. {
  2874. gc->procs.phong.ComputeRGBColor = ComputeRGBColorVanFast;
  2875. }
  2876. else
  2877. {
  2878. gc->procs.phong.ComputeRGBColor = ComputeRGBColorVanZippy;
  2879. }
  2880. }
  2881. }
  2882. else
  2883. {
  2884. ASSERTOPENGL (!anySlow, "Slow lights currently turned off\n");
  2885. gc->procs.phong.InitSpanInterpolation = InitSpanInterpolationAccel;
  2886. gc->procs.phong.UpdateAlongSpan = UpdateParamsAlongSpanAccel;
  2887. gc->procs.phong.InitLineParams = InitLineParamsAccel;
  2888. gc->procs.phong.ComputeCIColor = ComputeCIColorAccelFast;
  2889. if (colorMaterial)
  2890. gc->procs.phong.ComputeRGBColor = ComputeRGBColorAccelFast;
  2891. else
  2892. gc->procs.phong.ComputeRGBColor = ComputeRGBColorAccelZippy;
  2893. }
  2894. }
  2895. void __glCalcForwardDifferences( GLint w, __GLfloat p0, __GLfloat p1,
  2896. __GLfloat p2, __GLfloat *d1, __GLfloat *d2 )
  2897. {
  2898. // Compute quadratic forward differences along a span of length w, from
  2899. // points p0, p1, p2
  2900. __GLfloat dx;
  2901. __GLfloat a0, a1, a2;
  2902. if( w < 2 ) {
  2903. *d1 = *d2 = 0.0f;
  2904. return;
  2905. }
  2906. dx = 1.0f / w; // normalization factor
  2907. // quadratic polynomial coefficients
  2908. a0 = p0;
  2909. a1 = ( -3.0f*p0 + 4.0f*p1 - p2) * dx;
  2910. a2 = 2.0f * (p0 - 2.0f*p1 + p2) * dx * dx;
  2911. #ifdef __DEBUG_PRINT
  2912. DbgPrint ("a2=%f, a1=%f, a0=%f\n", a2, a1, a0);
  2913. #endif
  2914. // forward difference parameters
  2915. *d1 = a1 + a2;
  2916. *d2 = 2.0f * a2;
  2917. }
  2918. #ifdef __JUNKED_CODE
  2919. void InitSpanInterpolationFast (__GLcontext *gc)
  2920. {
  2921. GLint i;
  2922. __GLphongShader *phong = &(gc->polygon.shader.phong);
  2923. phong->tmp_pos.x = phong->cur_pos.x;
  2924. phong->tmp_pos.y = phong->cur_pos.y;
  2925. for (i=0; i<phong->numLights; i++)
  2926. {
  2927. __GLphongPerLightData *pld = &(phong->perLight[i]);
  2928. /* Diffuse */
  2929. pld->D_tmp = pld->D_curr;
  2930. pld->Ddel_tmp = pld->DdelSpan;
  2931. /* Specular */
  2932. pld->S_tmp = pld->S_curr;
  2933. pld->Sdel_tmp = pld->SdelSpan;
  2934. }
  2935. }
  2936. #ifdef __TWO
  2937. ASSERTOPENGL (!anySlow, "Slow lights currently turned off\n");
  2938. gc->procs.phong.InitInterpolation = InitializePhongInterpolationVan;
  2939. gc->procs.phong.SetInitParams = SetInitialPhongInterpolationVan;
  2940. gc->procs.phong.UpdateAlongEdge = UpdateParamsAlongEdgeVan;
  2941. gc->procs.phong.InitSpanInterpolation = InitSpanInterpolationTWO;
  2942. gc->procs.phong.UpdateAlongSpan = UpdateParamsAlongSpanFast;
  2943. //Line related
  2944. gc->procs.phong.InitLineParams = InitLineParamsFast;
  2945. if (colorMaterial)
  2946. gc->procs.phong.ComputeRGBColor = ComputeRGBColorAccelFast;
  2947. else
  2948. gc->procs.phong.ComputeRGBColor = ComputeRGBColorAccelZippy;
  2949. #else
  2950. gc->procs.phong.InitInterpolation = InitializePhongInterpolationFast;
  2951. gc->procs.phong.SetInitParams = SetInitialPhongInterpolationFast;
  2952. gc->procs.phong.UpdateAlongEdge = UpdateParamsAlongEdgeFast;
  2953. gc->procs.phong.InitSpanInterpolation = InitSpanInterpolationFast;
  2954. gc->procs.phong.UpdateAlongSpan = UpdateParamsAlongSpanFast;
  2955. gc->procs.phong.ComputeCIColor = ComputeCIColorAccelFast;
  2956. //Line related
  2957. gc->procs.phong.InitLineParams = InitLineParamsFast;
  2958. if (colorMaterial)
  2959. gc->procs.phong.ComputeRGBColor = ComputeRGBColorAccelFast;
  2960. else
  2961. gc->procs.phong.ComputeRGBColor = ComputeRGBColorAccelZippy;
  2962. #endif
  2963. void InitSpanInterpolationTWO (__GLcontext *gc)
  2964. {
  2965. __GLphongShader *phong = &(gc->polygon.shader.phong);
  2966. GLint face = phong->face;
  2967. __GLlightSourceMachine *lsm;
  2968. //__GLmaterialMachine *msm;
  2969. __GLcoord n, dndx;
  2970. __GLcoord *A = &dndx;
  2971. __GLcoord *C = &n;
  2972. __GLfloat a, b, c, d, e, f, g, h, i;
  2973. GLint curL;
  2974. if (face == __GL_FRONTFACE)
  2975. {
  2976. //msm = &gc->light.front;
  2977. n.x = phong->nCur.x;
  2978. n.y = phong->nCur.y;
  2979. n.z = phong->nCur.z;
  2980. dndx.x = phong->dndx.x;
  2981. dndx.y = phong->dndx.y;
  2982. dndx.z = phong->dndx.z;
  2983. }
  2984. else
  2985. {
  2986. //msm = &gc->light.back;
  2987. n.x = -phong->nCur.x;
  2988. n.y = -phong->nCur.y;
  2989. n.z = -phong->nCur.z;
  2990. dndx.x = -phong->dndx.x;
  2991. dndx.y = -phong->dndx.y;
  2992. dndx.z = -phong->dndx.z;
  2993. }
  2994. if (gc->state.enables.general & __GL_NORMALIZE_ENABLE)
  2995. __glNormalize(&n.x, &n.x);
  2996. MAGN2 (d,A); //d = A.A
  2997. DOT (g,A,C); g *= 2.0; //g = 2A.C
  2998. MAGN2 (i,C); //i = C.C
  2999. for (lsm = gc->light.sources, curL=0; lsm; lsm = lsm->next, curL++)
  3000. {
  3001. __GLfloat i2, iRt, tmp5, tmp2;
  3002. __GLphongPerLightData *pld = &(phong->perLight[curL]);
  3003. __GLcoord *L = &(lsm->unitVPpli); // L is already normalized here
  3004. __GLcoord *H = &(lsm->hHat); // H is already normalized here
  3005. i2 = (i*i);
  3006. iRt = __GL_SQRTF(i);
  3007. /***** Diffuse *****/
  3008. // Remaining Bishop parameters
  3009. DOT (a,L,A); //a = L.A/|L|
  3010. DOT (c,L,C); //c = L.C/|L|
  3011. tmp2 = (2.0*a*i - c*g)/(2.0*i*iRt);
  3012. tmp5 = (3.0*c*g*g - 4.0*c*d*i - 4.0*a*g*i)/(8.0*i2*iRt);
  3013. // Constant deltas
  3014. pld->Ddel2Span = 2*tmp5;
  3015. pld->Ddel_tmp = tmp2 + tmp5;
  3016. pld->D_tmp = c/iRt;
  3017. /***** Specular ******/
  3018. // Remaining Bishop parameters
  3019. DOT (a,H,A); //a = H.A/|H|
  3020. DOT (c,H,C); //c = H.C/|H|
  3021. // Polynomial coefficients
  3022. tmp2 = (2.0*a*i - c*g)/(2.0*i*iRt);
  3023. tmp5 = (3.0*c*g*g - 4.0*c*d*i - 4.0*a*g*i)/(8.0*i2*iRt);
  3024. // Constant deltas
  3025. pld->Sdel2Span = 2*tmp5;
  3026. pld->Sdel_tmp = tmp2 + tmp5;
  3027. pld->S_tmp = c/iRt;
  3028. }
  3029. phong->numLights = curL;
  3030. }
  3031. void SetInitialPhongInterpolationVan (__GLcontext *gc, __GLvertex *a,
  3032. __GLcoord *an, __GLfloat dx,
  3033. __GLfloat dy)
  3034. {
  3035. __GLshade *sh = &gc->polygon.shader;
  3036. __GLphongShader *phong = &gc->polygon.shader.phong;
  3037. __GLfloat little = sh->dxLeftLittle;
  3038. __GLfloat big = sh->dxLeftBig;
  3039. phong->nCur.x = an->x + dx*phong->dndx.x + dy*phong->dndy.x;
  3040. phong->nCur.y = an->y + dx*phong->dndx.y + dy*phong->dndy.y;
  3041. phong->nCur.z = an->z + dx*phong->dndx.z + dy*phong->dndy.z;
  3042. phong->nLittle.x = phong->dndy.x + little * phong->dndx.x;
  3043. phong->nLittle.y = phong->dndy.y + little * phong->dndx.y;
  3044. phong->nLittle.z = phong->dndy.z + little * phong->dndx.z;
  3045. if (big > little)
  3046. {
  3047. phong->nBig.x = phong->nLittle.x + phong->dndx.x;
  3048. phong->nBig.y = phong->nLittle.y + phong->dndx.y;
  3049. phong->nBig.z = phong->nLittle.z + phong->dndx.z;
  3050. }
  3051. else
  3052. {
  3053. phong->nBig.x = phong->nLittle.x - phong->dndx.x;
  3054. phong->nBig.y = phong->nLittle.y - phong->dndx.y;
  3055. phong->nBig.z = phong->nLittle.z - phong->dndx.z;
  3056. }
  3057. if (phong->flags & __GL_PHONG_NEED_EYE_XPOLATE)
  3058. {
  3059. phong->eCur.x = a->eyeX + dx*phong->dedx.x + dy*phong->dedy.x;
  3060. phong->eCur.y = a->eyeY + dx*phong->dedx.y + dy*phong->dedy.y;
  3061. phong->eCur.z = a->eyeZ + dx*phong->dedx.z + dy*phong->dedy.z;
  3062. phong->eCur.w = a->eyeW + dx*phong->dedx.w + dy*phong->dedy.w;
  3063. phong->eLittle.x = phong->dedy.x + little * phong->dedx.x;
  3064. phong->eLittle.y = phong->dedy.y + little * phong->dedx.y;
  3065. phong->eLittle.z = phong->dedy.z + little * phong->dedx.z;
  3066. phong->eLittle.w = phong->dedy.w + little * phong->dedx.w;
  3067. if (big > little)
  3068. {
  3069. phong->eBig.x = phong->eLittle.x + phong->dedx.x;
  3070. phong->eBig.y = phong->eLittle.y + phong->dedx.y;
  3071. phong->eBig.z = phong->eLittle.z + phong->dedx.z;
  3072. phong->eBig.w = phong->eLittle.w + phong->dedx.w;
  3073. }
  3074. else
  3075. {
  3076. phong->eBig.x = phong->eLittle.x - phong->dedx.x;
  3077. phong->eBig.y = phong->eLittle.y - phong->dedx.y;
  3078. phong->eBig.z = phong->eLittle.z - phong->dedx.z;
  3079. phong->eBig.w = phong->eLittle.w - phong->dedx.w;
  3080. }
  3081. }
  3082. }
  3083. /* Equivalent to SetInitialPhongParameters. Does for D and S */
  3084. void SetInitialPhongInterpolationFast (__GLcontext *gc, __GLvertex *a,
  3085. __GLcoord *an, __GLfloat dx,
  3086. __GLfloat dy)
  3087. {
  3088. __GLshade *sh = &gc->polygon.shader;
  3089. __GLphongShader *phong = &gc->polygon.shader.phong;
  3090. __GLfloat little = sh->dxLeftLittle;
  3091. __GLfloat little2 = little*little;
  3092. __GLfloat big = sh->dxLeftBig;
  3093. __GLfloat big2 = big*big;
  3094. __GLfloat dx2 = dx*dx;
  3095. __GLfloat dy2 = dy*dy;
  3096. __GLcoord pos;
  3097. int i;
  3098. GLfloat x, x2, y, y2;
  3099. GLfloat aa, b, c, d, e, f, g, h, ii;
  3100. phong->cur_pos.x += dx;
  3101. phong->cur_pos.y += dy;
  3102. pos = phong->cur_pos;
  3103. x = phong->cur_pos.x; x2 = x*x;
  3104. y = phong->cur_pos.y; y2 = y*y;
  3105. for (i = 0; i<phong->numLights; i++)
  3106. {
  3107. __GLphongPerLightData *pld = &phong->perLight[i];
  3108. __GLfloat tmp1, tmp2, tmp3;
  3109. /**** Diffuse Parameters *****/
  3110. pld->D_curr = pld->D[5]*x2 + pld->D[4]*x*y + pld->D[3]*y2 +
  3111. pld->D[2]*x + pld->D[1]*y + pld->D[0];
  3112. tmp1 = 2*pld->D[5]*x + pld->D[4]*y + pld->D[2];
  3113. tmp2 = 2*pld->D[3]*y + pld->D[4]*x + pld->D[1];
  3114. // Compute the along-edge del2 and del terms (Little)
  3115. tmp3 = pld->D[5]*little2 + pld->D[4]*little + pld->D[3];
  3116. pld->Ddel2EdgeLittle = 2*tmp3;
  3117. pld->DdelEdgeLittle = tmp1*little + tmp2 + tmp3;
  3118. // Compute the along-edge del2 and del terms (Big)
  3119. tmp3 = pld->D[5]*big2 + pld->D[4]*big + pld->D[3];
  3120. pld->Ddel2EdgeBig = 2*tmp3;
  3121. pld->DdelEdgeBig = tmp1*big + tmp2 + tmp3;
  3122. // Compute the along-span del terms
  3123. pld->DdelSpan = tmp1 + pld->D[5];
  3124. pld->DdelSpanEdgeBig = pld->D[4] + 2*pld->D[5]*big;
  3125. pld->DdelSpanEdgeLittle = pld->D[4] + 2*pld->D[5]*little;
  3126. /**** Specular Parameters ****/
  3127. #ifndef __SLOW
  3128. pld->S_curr = pld->S[5]*x2 + pld->S[4]*x*y + pld->S[3]*y2 +
  3129. pld->S[2]*x + pld->S[1]*y + pld->S[0];
  3130. #else
  3131. aa = pld->A[0]; b = pld->A[1];
  3132. c = pld->A[2]; d = pld->A[3];
  3133. e = pld->A[4]; f = pld->A[5];
  3134. g = pld->A[6]; h = pld->A[7];
  3135. ii = pld->A[8];
  3136. pld->S_curr = (aa*x+b*y+c)/__GL_SQRTF(d*x2+e*x*y+f*y2+g*x+h*y+ii);
  3137. #endif
  3138. tmp1 = 2*pld->S[5]*x + pld->S[4]*y + pld->S[2];
  3139. tmp2 = 2*pld->S[3]*y + pld->S[4]*x + pld->S[1];
  3140. // Compute the along-edge del2 and del terms (Little)
  3141. tmp3 = pld->S[5]*little2 + pld->S[4]*little + pld->S[3];
  3142. pld->Sdel2EdgeLittle = 2*tmp3;
  3143. pld->SdelEdgeLittle = tmp1*little + tmp2 + tmp3;
  3144. // Compute the along-edge del2 and del terms (Big)
  3145. tmp3 = pld->S[5]*big2 + pld->S[4]*big + pld->S[3];
  3146. pld->Sdel2EdgeBig = 2*tmp3;
  3147. pld->SdelEdgeBig = tmp1*big + tmp2 + tmp3;
  3148. // Compute the along-span del terms
  3149. pld->SdelSpan = tmp1 + pld->S[5];
  3150. pld->SdelSpanEdgeBig = pld->S[4] + 2*pld->S[5]*big;
  3151. pld->SdelSpanEdgeLittle = pld->S[4] + 2*pld->S[5]*little;
  3152. }
  3153. }
  3154. /* Called when: Normalization Enabled, FastLights */
  3155. /******************************************************
  3156. ****Set up the Polynomial for diffuse illumination****
  3157. ******************************************************
  3158. * *
  3159. * 2 2 *
  3160. * SD (x,y) = D_5x + D_4xy + D_3y + D_2x + D_1y + D_0 *
  3161. * *
  3162. * D_i are expressed in terms of: a,b,c,d,e,f,g,h,i *
  3163. * *
  3164. * D_0 = c/sqrt(i) *
  3165. * D_1 = (2bi - ch)/(2i*sqrt(i)) *
  3166. * D_2 = (2ai - cg)/(2i*sqrt(i)) *
  3167. * D_3 = (3ch^2 - 4cfi - 4bhi)/(4i^2*sqrt(i)) *
  3168. * D_4 = (3cgh - 2ci - 2bgi - 2ahi)/(8i^2*sqrt(i)) *
  3169. * D_5 = (3ig^2 - 4cdi - 4agi)/(4i^2*sqrt(i)) *
  3170. ******************************************************/
  3171. void InitializePhongInterpolationFast (__GLcontext *gc, __GLvertex *v)
  3172. {
  3173. GLboolean colorMaterial = (gc->state.enables.general &
  3174. __GL_COLOR_MATERIAL_ENABLE);
  3175. GLint face = gc->polygon.shader.phong.face;
  3176. __GLlightSourcePerMaterialMachine *lspmm;
  3177. __GLlightSourceMachine *lsm;
  3178. __GLmaterialMachine *msm;
  3179. GLuint msm_colorMaterialChange;
  3180. __GLfloat msm_alpha;
  3181. __GLfloat rsi, gsi, bsi;
  3182. __GLcoord normal;
  3183. GLint curL;
  3184. __GLphongShader *phong = &gc->polygon.shader.phong;
  3185. __GLshade *sh = &gc->polygon.shader;
  3186. __GLfloat little = sh->dxLeftLittle;
  3187. __GLfloat big = sh->dxLeftBig;
  3188. __GLcoord *A = &(phong->dndx);
  3189. __GLcoord *B = &(phong->dndy);
  3190. __GLcoord *C;
  3191. //From Bishop's paper
  3192. __GLfloat a, b, c, d, e, f, g, h, i;
  3193. #ifdef __CENTER
  3194. normal.x = v->normal.x + (v->window.x - phong->center.x)*A->x
  3195. + (v->window.y - phong->center.y)*B->x;
  3196. normal.y = v->normal.y + (v->window.x - phong->center.x)*A->y
  3197. + (v->window.y - phong->center.y)*B->y;
  3198. normal.z = v->normal.z + (v->window.x - phong->center.x)*A->z
  3199. + (v->window.y - phong->center.y)*B->z;
  3200. #else
  3201. normal.x = v->normal.x;
  3202. normal.y = v->normal.y;
  3203. normal.z = v->normal.z;
  3204. #endif
  3205. if (face == __GL_FRONTFACE)
  3206. {
  3207. msm = &gc->light.front;
  3208. }
  3209. else
  3210. {
  3211. msm = &gc->light.back;
  3212. normal.x = -normal.x;
  3213. normal.y = -normal.y;
  3214. normal.z = -normal.z;
  3215. }
  3216. C = &normal;
  3217. //msm_colorMaterialChange = msm->colorMaterialChange;
  3218. #ifdef __DBG_PRINT
  3219. DbgPrint ("A = (%f, %f, %f)\n", A->x, A->y, A->z);
  3220. DbgPrint ("B = (%f, %f, %f)\n", B->x, B->y, B->z);
  3221. DbgPrint ("C = (%f, %f, %f)\n", C->x, C->y, C->z);
  3222. #endif
  3223. //***********Diffuse Bishop Parameters*****************************
  3224. //a, b, c depend upon the light vector, so compute inside the loop
  3225. //d, e, f, g, h, i depend only upon the incoming normal
  3226. MAGN2 (d, A); //d = A.A
  3227. DOT (e,A,B); e *= 2.0; //e = 2A.B
  3228. MAGN2 (f, B); //f = B.B
  3229. DOT (g,A,C); g *= 2.0; //g = 2A.C
  3230. DOT (h,B,C); h *= 2.0; //h = 2B.C
  3231. MAGN2 (i,C); //i = C.C
  3232. // Normalization not needed since
  3233. // it was done (if needed) during normal propagation.
  3234. // Compute the per-light interpolation parameters
  3235. for (lsm = gc->light.sources, curL = 0; lsm;
  3236. lsm = lsm->next, curL++)
  3237. {
  3238. __GLphongPerLightData *pld = &(phong->perLight[curL]);
  3239. __GLcoord *L = &(lsm->unitVPpli); // L is already normalized here
  3240. __GLcoord *H = &(lsm->hHat); // H is already normalized here
  3241. GLfloat i2, iRt;
  3242. i2 = i*i;
  3243. iRt = __GL_SQRTF(i);
  3244. /***** Diffuse *****/
  3245. // Remaining Bishop parameters
  3246. DOT (a,L,A); //a = L.A/|L|
  3247. DOT (b,L,B); //b = L.B/|L|
  3248. DOT (c,L,C); //c = L.C/|L|
  3249. // Polynomial coefficients
  3250. //DOT (pld->D[0], &normal, L);
  3251. pld->D[0] = c/iRt;
  3252. pld->D[1] = (2.0*b*i - c*h)/(2.0*i*iRt);
  3253. pld->D[2] = (2.0*a*i - c*g)/(2.0*i*iRt);
  3254. pld->D[3] = (3.0*c*h*h - 4.0*c*f*i - 4.0*b*h*i)/(8.0*i2*iRt);
  3255. pld->D[4] = (3.0*c*g*h - 2.0*c*e*i - 2.0*b*g*i - 2.0*a*h*i)/
  3256. (4.0*i2*iRt);
  3257. pld->D[5] = (3.0*c*g*g - 4.0*c*d*i - 4.0*a*g*i)/(8.0*i2*iRt);
  3258. #ifdef __DBG_PRINT
  3259. DbgPrint ("D[0]= %f, D[1]=%f, D[2]=%f, D[3]=%f, D[4]=%f, D[5]=%f\n",
  3260. pld->D[0], pld->D[1], pld->D[2], pld->D[3], pld->D[4],
  3261. pld->D[5]);
  3262. #endif
  3263. // Constant deltas
  3264. pld->Ddel2Span = 2*pld->D[5];
  3265. pld->D_curr = pld->D[0];
  3266. #ifdef __DBG_PRINT
  3267. DbgPrint ("Ddel2Span= %f, D_curr=%f\n", pld->Ddel2Span, pld->D_curr);
  3268. #endif
  3269. /***** Specular ******/
  3270. // Remaining Bishop parameters
  3271. DOT (a,H,A); //a = H.A/|H|
  3272. DOT (b,H,B); //b = H.B/|H|
  3273. DOT (c,H,C); //c = H.C/|H|
  3274. // Polynomial coefficients
  3275. DOT (pld->S[0], &normal, H);
  3276. pld->S[1] = (2.0*b*i - c*h)/(2.0*i*iRt);
  3277. pld->S[2] = (2.0*a*i - c*g)/(2.0*i*iRt);
  3278. pld->S[3] = (3.0*c*h*h - 4.0*c*f*i - 4.0*b*h*i)/(8.0*i2*iRt);
  3279. pld->S[4] = (3.0*c*g*h - 2.0*c*e*i - 2.0*b*g*i - 2.0*a*h*i)/
  3280. (4.0*i2*iRt);
  3281. pld->S[5] = (3.0*c*g*g - 4.0*c*d*i - 4.0*a*g*i)/(8.0*i2*iRt);
  3282. // Constant deltas
  3283. pld->Sdel2Span = 2*pld->S[5];
  3284. pld->S_curr = pld->S[0];
  3285. #ifdef __SLOW
  3286. pld->A[0] = a; pld->A[1] = b;
  3287. pld->A[2] = c; pld->A[3] = d;
  3288. pld->A[4] = e; pld->A[5] = f;
  3289. pld->A[6] = g; pld->A[7] = h;
  3290. pld->A[8] = i;
  3291. #endif
  3292. #ifdef __DBG_PRINT
  3293. DbgPrint ("L = (%f, %f, %f)\n", L->x, L->y, L->z);
  3294. DbgPrint ("H = (%f, %f, %f)\n", H->x, H->y, H->z);
  3295. DbgPrint ("a= %f, b=%f, c=%f, d=%f, e=%f, f=%f, g=%f, h=%f, i=%f\n",
  3296. a, b, c, d, e, f, g, h, i);
  3297. #endif
  3298. }
  3299. phong->numLights = curL;
  3300. #ifdef __CENTER
  3301. phong->cur_pos.x = v->window.x - phong->center.x;
  3302. phong->cur_pos.y = v->window.y - phong->center.y;
  3303. #else
  3304. phong->cur_pos.x = 0.0;
  3305. phong->cur_pos.y = 0.0;
  3306. #endif
  3307. }
  3308. void InitializePhongInterpolationSlow (__GLcontext *gc, __GLvertex *v)
  3309. {
  3310. }
  3311. /* Do nothing */
  3312. void InitializePhongInterpolationVan (__GLcontext *gc, __GLvertex *v)
  3313. {
  3314. __GLphongShader *phong = &gc->polygon.shader.phong;
  3315. #ifdef __DBG_PRINT
  3316. DbgPrint ("dndx = (%f, %f, %f)\n", phong->dndx.x, phong->dndx.y,
  3317. phong->dndx.z);
  3318. DbgPrint ("dndy = (%f, %f, %f)\n", phong->dndy.x, phong->dndy.y,
  3319. phong->dndy.z);
  3320. DbgPrint ("normal = (%f, %f, %f)\n", v->normal.x, v->normal.y,
  3321. v->normal.z);
  3322. #endif
  3323. }
  3324. void UpdateParamsAlongEdgeFast (__GLcontext *gc, __GLfloat dxLeft,
  3325. GLboolean useBigStep)
  3326. {
  3327. __GLphongShader *phong = &(gc->polygon.shader.phong);
  3328. __GLphongPerLightData *pld;
  3329. GLint i;
  3330. if (useBigStep)
  3331. {
  3332. for (i=0; i<phong->numLights; i++)
  3333. {
  3334. pld = &(phong->perLight[i]);
  3335. /** Diffuse Parameters **/
  3336. pld->D_curr += pld->DdelEdgeBig;
  3337. pld->DdelEdgeBig += pld->Ddel2EdgeBig;
  3338. pld->DdelEdgeLittle += pld->Ddel2EdgeBig;
  3339. pld->DdelSpan += pld->DdelSpanEdgeBig;
  3340. /** Specular Parameters **/
  3341. pld->S_curr += pld->SdelEdgeBig;
  3342. pld->SdelEdgeBig += pld->Sdel2EdgeBig;
  3343. pld->SdelEdgeLittle += pld->Sdel2EdgeBig;
  3344. pld->SdelSpan += pld->SdelSpanEdgeBig;
  3345. }
  3346. }
  3347. else //Use small step
  3348. {
  3349. for (i=0; i<phong->numLights; i++)
  3350. {
  3351. pld = &(phong->perLight[i]);
  3352. /** Diffuse Parameters **/
  3353. pld->D_curr += pld->DdelEdgeLittle;
  3354. pld->DdelEdgeBig += pld->Ddel2EdgeLittle;
  3355. pld->DdelEdgeLittle += pld->Ddel2EdgeLittle;
  3356. pld->DdelSpan += pld->DdelSpanEdgeLittle;
  3357. /** Specular Parameters **/
  3358. pld->S_curr += pld->SdelEdgeLittle;
  3359. pld->SdelEdgeBig += pld->Sdel2EdgeLittle;
  3360. pld->SdelEdgeLittle += pld->Sdel2EdgeLittle;
  3361. pld->SdelSpan += pld->SdelSpanEdgeLittle;
  3362. }
  3363. }
  3364. phong->cur_pos.x += dxLeft;
  3365. phong->cur_pos.y += 1.0;
  3366. }
  3367. void UpdateParamsAlongEdgeVan (__GLcontext *gc, __GLfloat dxLeft,
  3368. GLboolean useBigStep)
  3369. {
  3370. __GLphongShader *phong = &(gc->polygon.shader.phong);
  3371. if (useBigStep)
  3372. {
  3373. phong->nCur.x += phong->nBig.x;
  3374. phong->nCur.y += phong->nBig.y;
  3375. phong->nCur.z += phong->nBig.z;
  3376. }
  3377. else
  3378. {
  3379. phong->nCur.x += phong->nLittle.x;
  3380. phong->nCur.y += phong->nLittle.y;
  3381. phong->nCur.z += phong->nLittle.z;
  3382. }
  3383. if (phong->flags & __GL_PHONG_NEED_EYE_XPOLATE)
  3384. {
  3385. if (useBigStep)
  3386. {
  3387. phong->eCur.x += phong->eBig.x;
  3388. phong->eCur.y += phong->eBig.y;
  3389. phong->eCur.z += phong->eBig.z;
  3390. phong->eCur.w += phong->eBig.w;
  3391. }
  3392. else
  3393. {
  3394. phong->eCur.x += phong->eLittle.x;
  3395. phong->eCur.y += phong->eLittle.y;
  3396. phong->eCur.z += phong->eLittle.z;
  3397. phong->eCur.w += phong->eLittle.w;
  3398. }
  3399. }
  3400. }
  3401. #endif //__JUNKED_CODE
  3402. #endif // GL_WIN_phong_shading