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.

992 lines
27 KiB

  1. /*
  2. ** Copyright 1991, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. **
  17. ** Lighting and coloring code.
  18. **
  19. ** $Revision: 1.42 $
  20. ** $Date: 1993/12/08 02:20:39 $
  21. */
  22. #include "precomp.h"
  23. #pragma hdrstop
  24. /*
  25. ** Scale an incoming color from the user.
  26. */
  27. void FASTCALL __glScaleColorf(__GLcontext *gc, __GLcolor *dst, const GLfloat src[4])
  28. {
  29. dst->r = src[0] * gc->redVertexScale;
  30. dst->g = src[1] * gc->greenVertexScale;
  31. dst->b = src[2] * gc->blueVertexScale;
  32. dst->a = src[3] * gc->alphaVertexScale;
  33. }
  34. /*
  35. ** Clamp and scale an incoming color from the user.
  36. */
  37. void FASTCALL __glClampAndScaleColorf(__GLcontext *gc, __GLcolor *d, const GLfloat s[4])
  38. {
  39. __GLfloat zero = __glZero;
  40. d->r = s[0] * gc->redVertexScale;
  41. if (d->r < zero) d->r = zero;
  42. if (d->r > gc->redVertexScale) d->r = gc->redVertexScale;
  43. d->g = s[1] * gc->greenVertexScale;
  44. if (d->g < zero) d->g = zero;
  45. if (d->g > gc->greenVertexScale) d->g = gc->greenVertexScale;
  46. d->b = s[2] * gc->blueVertexScale;
  47. if (d->b < zero) d->b = zero;
  48. if (d->b > gc->blueVertexScale) d->b = gc->blueVertexScale;
  49. d->a = s[3] * gc->alphaVertexScale;
  50. if (d->a < zero) d->a = zero;
  51. if (d->a > gc->alphaVertexScale) d->a = gc->alphaVertexScale;
  52. }
  53. /*
  54. ** Clamp an incoming color from the user.
  55. */
  56. void FASTCALL __glClampColorf(__GLcontext *gc, __GLcolor *d, const GLfloat s[4])
  57. {
  58. __GLfloat zero = __glZero;
  59. __GLfloat one = __glOne;
  60. __GLfloat r,g,b,a;
  61. r = s[0];
  62. g = s[1];
  63. b = s[2];
  64. a = s[3];
  65. if (r < zero) d->r = zero;
  66. else if (r > one) d->r = one;
  67. else d->r = r;
  68. if (g < zero) d->g = zero;
  69. else if (g > one) d->g = one;
  70. else d->g = g;
  71. if (b < zero) d->b = zero;
  72. else if (b > one) d->b = one;
  73. else d->b = b;
  74. if (a < zero) d->a = zero;
  75. else if (a > one) d->a = one;
  76. else d->a = a;
  77. }
  78. /*
  79. ** Clamp and scale an incoming color from the user.
  80. */
  81. void FASTCALL __glClampAndScaleColori(__GLcontext *gc, __GLcolor *d, const GLint s[4])
  82. {
  83. __GLfloat zero = __glZero;
  84. d->r = __GL_I_TO_FLOAT(s[0]) * gc->redVertexScale;
  85. if (d->r < zero) d->r = zero;
  86. if (d->r > gc->redVertexScale) d->r = gc->redVertexScale;
  87. d->g = __GL_I_TO_FLOAT(s[1]) * gc->greenVertexScale;
  88. if (d->g < zero) d->g = zero;
  89. if (d->g > gc->greenVertexScale) d->g = gc->greenVertexScale;
  90. d->b = __GL_I_TO_FLOAT(s[2]) * gc->blueVertexScale;
  91. if (d->b < zero) d->b = zero;
  92. if (d->b > gc->blueVertexScale) d->b = gc->blueVertexScale;
  93. d->a = __GL_I_TO_FLOAT(s[3]) * gc->alphaVertexScale;
  94. if (d->a < zero) d->a = zero;
  95. if (d->a > gc->alphaVertexScale) d->a = gc->alphaVertexScale;
  96. }
  97. /*
  98. ** Clamp an incoming color from the user.
  99. */
  100. void FASTCALL __glClampColori(__GLcontext *gc, __GLcolor *d, const GLint s[4])
  101. {
  102. __GLfloat zero = __glZero;
  103. __GLfloat one = __glOne;
  104. __GLfloat r,g,b,a;
  105. r = __GL_I_TO_FLOAT(s[0]);
  106. g = __GL_I_TO_FLOAT(s[1]);
  107. b = __GL_I_TO_FLOAT(s[2]);
  108. a = __GL_I_TO_FLOAT(s[3]);
  109. if (r < zero) d->r = zero;
  110. else if (r > one) d->r = one;
  111. else d->r = r;
  112. if (g < zero) d->g = zero;
  113. else if (g > one) d->g = one;
  114. else d->g = g;
  115. if (b < zero) d->b = zero;
  116. else if (b > one) d->b = one;
  117. else d->b = b;
  118. if (a < zero) d->a = zero;
  119. else if (a > one) d->a = one;
  120. else d->a = a;
  121. }
  122. /*
  123. ** Reverse the scaling back to the users original
  124. */
  125. void FASTCALL __glUnScaleColorf(__GLcontext *gc, GLfloat dst[4], const __GLcolor* src)
  126. {
  127. dst[0] = src->r * gc->oneOverRedVertexScale;
  128. dst[1] = src->g * gc->oneOverGreenVertexScale;
  129. dst[2] = src->b * gc->oneOverBlueVertexScale;
  130. dst[3] = src->a * gc->oneOverAlphaVertexScale;
  131. }
  132. /*
  133. ** Reverse the scaling back to the users original
  134. */
  135. void FASTCALL __glUnScaleColori(__GLcontext *gc, GLint dst[4], const __GLcolor* src)
  136. {
  137. dst[0] = __GL_FLOAT_TO_I(src->r * gc->oneOverRedVertexScale);
  138. dst[1] = __GL_FLOAT_TO_I(src->g * gc->oneOverGreenVertexScale);
  139. dst[2] = __GL_FLOAT_TO_I(src->b * gc->oneOverBlueVertexScale);
  140. dst[3] = __GL_FLOAT_TO_I(src->a * gc->oneOverAlphaVertexScale);
  141. }
  142. /*
  143. ** Clamp an already scaled RGB color.
  144. */
  145. void FASTCALL __glClampRGBColor(__GLcontext *gc, __GLcolor *dst, const __GLcolor *src)
  146. {
  147. __GLfloat zero = __glZero;
  148. __GLfloat r, g, b, a;
  149. __GLfloat rl, gl, bl, al;
  150. r = src->r; rl = gc->redVertexScale;
  151. if (r <= zero) {
  152. dst->r = zero;
  153. } else {
  154. if (r >= rl) {
  155. dst->r = rl;
  156. } else {
  157. dst->r = r;
  158. }
  159. }
  160. g = src->g; gl = gc->greenVertexScale;
  161. if (g <= zero) {
  162. dst->g = zero;
  163. } else {
  164. if (g >= gl) {
  165. dst->g = gl;
  166. } else {
  167. dst->g = g;
  168. }
  169. }
  170. b = src->b; bl = gc->blueVertexScale;
  171. if (b <= zero) {
  172. dst->b = zero;
  173. } else {
  174. if (b >= bl) {
  175. dst->b = bl;
  176. } else {
  177. dst->b = b;
  178. }
  179. }
  180. a = src->a; al = gc->alphaVertexScale;
  181. if (a <= zero) {
  182. dst->a = zero;
  183. } else {
  184. if (a >= al) {
  185. dst->a = al;
  186. } else {
  187. dst->a = a;
  188. }
  189. }
  190. }
  191. /************************************************************************/
  192. /*
  193. ** gc->procs.applyColor procs. These are used to apply the current color
  194. ** change to either a material color, or to current.color (when not
  195. ** lighting), preparing the color for copying into the vertex.
  196. */
  197. void FASTCALL ChangeMaterialEmission(__GLcontext *gc, __GLmaterialState *ms,
  198. __GLmaterialMachine *msm)
  199. {
  200. __GLfloat r, g, b;
  201. r = gc->state.current.userColor.r * gc->redVertexScale;
  202. g = gc->state.current.userColor.g * gc->greenVertexScale;
  203. b = gc->state.current.userColor.b * gc->blueVertexScale;
  204. ms->emissive.r = r;
  205. ms->emissive.g = g;
  206. ms->emissive.b = b;
  207. ms->emissive.a = gc->state.current.userColor.a * gc->alphaVertexScale;
  208. #ifdef NT
  209. // compute the invariant scene color
  210. msm->paSceneColor.r = ms->ambient.r * gc->state.light.model.ambient.r;
  211. msm->paSceneColor.g = ms->ambient.g * gc->state.light.model.ambient.g;
  212. msm->paSceneColor.b = ms->ambient.b * gc->state.light.model.ambient.b;
  213. #else
  214. msm->sceneColor.r = r + ms->ambient.r * gc->state.light.model.ambient.r;
  215. msm->sceneColor.g = g + ms->ambient.g * gc->state.light.model.ambient.g;
  216. msm->sceneColor.b = b + ms->ambient.b * gc->state.light.model.ambient.b;
  217. #endif
  218. }
  219. void FASTCALL ChangeMaterialSpecular(__GLcontext *gc, __GLmaterialState *ms,
  220. __GLmaterialMachine *msm)
  221. {
  222. __GLlightSourcePerMaterialMachine *lspmm;
  223. __GLlightSourceMachine *lsm;
  224. __GLlightSourceState *lss;
  225. GLboolean isBack;
  226. __GLfloat r, g, b;
  227. r = gc->state.current.userColor.r;
  228. g = gc->state.current.userColor.g;
  229. b = gc->state.current.userColor.b;
  230. ms->specular.r = r;
  231. ms->specular.g = g;
  232. ms->specular.b = b;
  233. ms->specular.a = gc->state.current.userColor.a;
  234. /*
  235. ** Update per-light-source state that depends on material specular
  236. ** state
  237. */
  238. isBack = msm == &gc->light.back;
  239. for (lsm = gc->light.sources; lsm; lsm = lsm->next) {
  240. lspmm = &lsm->front + isBack;
  241. lss = lsm->state;
  242. /* Recompute per-light per-material cached specular */
  243. lspmm->specular.r = r * lss->specular.r;
  244. lspmm->specular.g = g * lss->specular.g;
  245. lspmm->specular.b = b * lss->specular.b;
  246. }
  247. }
  248. void FASTCALL ChangeMaterialAmbient(__GLcontext *gc, __GLmaterialState *ms,
  249. __GLmaterialMachine *msm)
  250. {
  251. __GLlightSourcePerMaterialMachine *lspmm;
  252. __GLlightSourceMachine *lsm;
  253. __GLlightSourceState *lss;
  254. GLboolean isBack;
  255. __GLfloat r, g, b;
  256. r = gc->state.current.userColor.r;
  257. g = gc->state.current.userColor.g;
  258. b = gc->state.current.userColor.b;
  259. ms->ambient.r = r;
  260. ms->ambient.g = g;
  261. ms->ambient.b = b;
  262. ms->ambient.a = gc->state.current.userColor.a;
  263. #ifdef NT
  264. // compute the invariant scene color
  265. msm->paSceneColor.r = ms->emissive.r;
  266. msm->paSceneColor.g = ms->emissive.g;
  267. msm->paSceneColor.b = ms->emissive.b;
  268. #else
  269. msm->sceneColor.r = ms->emissive.r + r * gc->state.light.model.ambient.r;
  270. msm->sceneColor.g = ms->emissive.g + g * gc->state.light.model.ambient.g;
  271. msm->sceneColor.b = ms->emissive.b + b * gc->state.light.model.ambient.b;
  272. #endif
  273. /*
  274. ** Update per-light-source state that depends on material ambient
  275. ** state.
  276. */
  277. isBack = msm == &gc->light.back;
  278. for (lsm = gc->light.sources; lsm; lsm = lsm->next) {
  279. lspmm = &lsm->front + isBack;
  280. lss = lsm->state;
  281. /* Recompute per-light per-material cached ambient */
  282. lspmm->ambient.r = r * lss->ambient.r;
  283. lspmm->ambient.g = g * lss->ambient.g;
  284. lspmm->ambient.b = b * lss->ambient.b;
  285. }
  286. }
  287. void FASTCALL ChangeMaterialDiffuse(__GLcontext *gc, __GLmaterialState *ms,
  288. __GLmaterialMachine *msm)
  289. {
  290. __GLlightSourcePerMaterialMachine *lspmm;
  291. __GLlightSourceMachine *lsm;
  292. __GLlightSourceState *lss;
  293. GLboolean isBack;
  294. __GLfloat r, g, b, a;
  295. r = gc->state.current.userColor.r;
  296. g = gc->state.current.userColor.g;
  297. b = gc->state.current.userColor.b;
  298. a = gc->state.current.userColor.a;
  299. ms->diffuse.r = r;
  300. ms->diffuse.g = g;
  301. ms->diffuse.b = b;
  302. ms->diffuse.a = a;
  303. if (a < __glZero) {
  304. a = __glZero;
  305. } else if (a > __glOne) {
  306. a = __glOne;
  307. }
  308. msm->alpha = a * gc->alphaVertexScale;
  309. /*
  310. ** Update per-light-source state that depends on material diffuse
  311. ** state.
  312. */
  313. isBack = msm == &gc->light.back;
  314. for (lsm = gc->light.sources; lsm; lsm = lsm->next) {
  315. lspmm = &lsm->front + isBack;
  316. lss = lsm->state;
  317. /* Recompute per-light per-material cached diffuse */
  318. lspmm->diffuse.r = r * lss->diffuse.r;
  319. lspmm->diffuse.g = g * lss->diffuse.g;
  320. lspmm->diffuse.b = b * lss->diffuse.b;
  321. }
  322. }
  323. void FASTCALL ChangeMaterialAmbientAndDiffuse(__GLcontext *gc,
  324. __GLmaterialState *ms,
  325. __GLmaterialMachine *msm)
  326. {
  327. __GLlightSourcePerMaterialMachine *lspmm;
  328. __GLlightSourceMachine *lsm;
  329. __GLlightSourceState *lss;
  330. GLboolean isBack;
  331. __GLfloat r, g, b, a;
  332. r = gc->state.current.userColor.r;
  333. g = gc->state.current.userColor.g;
  334. b = gc->state.current.userColor.b;
  335. a = gc->state.current.userColor.a;
  336. ms->ambient.r = r;
  337. ms->ambient.g = g;
  338. ms->ambient.b = b;
  339. ms->ambient.a = a;
  340. ms->diffuse.r = r;
  341. ms->diffuse.g = g;
  342. ms->diffuse.b = b;
  343. ms->diffuse.a = a;
  344. #ifdef NT
  345. // compute the invariant scene color
  346. msm->paSceneColor.r = ms->emissive.r;
  347. msm->paSceneColor.g = ms->emissive.g;
  348. msm->paSceneColor.b = ms->emissive.b;
  349. #else
  350. msm->sceneColor.r = ms->emissive.r + r * gc->state.light.model.ambient.r;
  351. msm->sceneColor.g = ms->emissive.g + g * gc->state.light.model.ambient.g;
  352. msm->sceneColor.b = ms->emissive.b + b * gc->state.light.model.ambient.b;
  353. #endif
  354. if (a < __glZero) {
  355. a = __glZero;
  356. } else if (a > __glOne) {
  357. a = __glOne;
  358. }
  359. msm->alpha = a * gc->alphaVertexScale;
  360. /*
  361. ** Update per-light-source state that depends on per-material state.
  362. */
  363. isBack = msm == &gc->light.back;
  364. for (lsm = gc->light.sources; lsm; lsm = lsm->next) {
  365. lspmm = &lsm->front + isBack;
  366. lss = lsm->state;
  367. /* Recompute per-light per-material cached ambient */
  368. lspmm->ambient.r = r * lss->ambient.r;
  369. lspmm->ambient.g = g * lss->ambient.g;
  370. lspmm->ambient.b = b * lss->ambient.b;
  371. /* Recompute per-light per-material cached diffuse */
  372. lspmm->diffuse.r = r * lss->diffuse.r;
  373. lspmm->diffuse.g = g * lss->diffuse.g;
  374. lspmm->diffuse.b = b * lss->diffuse.b;
  375. }
  376. }
  377. void FASTCALL __glChangeOneMaterialColor(__GLcontext *gc)
  378. {
  379. (*gc->procs.changeMaterial)(gc, gc->light.cm, gc->light.cmm);
  380. }
  381. void FASTCALL __glChangeBothMaterialColors(__GLcontext *gc)
  382. {
  383. (*gc->procs.changeMaterial)(gc, &gc->state.light.front, &gc->light.front);
  384. (*gc->procs.changeMaterial)(gc, &gc->state.light.back, &gc->light.back);
  385. }
  386. /************************************************************************/
  387. /*
  388. ** DEPENDENCIES:
  389. **
  390. ** Material EMISSIVE, AMBIENT, DIFFUSE, SHININESS
  391. ** Light Model AMBIENT
  392. */
  393. /*
  394. ** Compute derived state for a material
  395. */
  396. void ComputeMaterialState(__GLcontext *gc, __GLmaterialState *ms,
  397. __GLmaterialMachine *msm, GLint changeBits)
  398. {
  399. GLdouble exponent;
  400. __GLspecLUTEntry *lut;
  401. if ((changeBits & (__GL_MATERIAL_EMISSIVE | __GL_MATERIAL_AMBIENT |
  402. __GL_MATERIAL_DIFFUSE | __GL_MATERIAL_SHININESS)) == 0) {
  403. return;
  404. }
  405. /* Only compute specular lookup table when it changes */
  406. if (!msm->cache || (ms->specularExponent != msm->specularExponent)) {
  407. /*
  408. ** Specular lookup table generation. Instead of performing a
  409. ** "pow" computation each time a vertex is lit, we generate a
  410. ** lookup table which approximates the pow function:
  411. **
  412. ** n2 = n circle-dot hHat[i]
  413. ** if (n2 >= threshold) {
  414. ** n2spec = specTable[n2 * scale];
  415. ** ...
  416. ** }
  417. **
  418. ** Remember that n2 is a value constrained to be between 0.0 and
  419. ** 1.0, inclusive (n is the normalized normal; hHat[i] is the
  420. ** unit h vector). "threshold" is the threshold where incoming
  421. ** n2 values become meaningful for a given exponent. The larger
  422. ** the specular exponent, the closer "threshold" will approach
  423. ** 1.0.
  424. **
  425. ** A simple linear mapping of the n2 value to a table index will
  426. ** not suffice because in most cases the majority of the table
  427. ** entries would be zero, while the useful non-zero values would
  428. ** be compressed into a few table entries. By setting up a
  429. ** threshold, we can use the entire table to represent the useful
  430. ** values beyond the threshold. "scale" is computed based on
  431. ** this threshold.
  432. */
  433. exponent = msm->specularExponent = ms->specularExponent;
  434. __glFreeSpecLUT(gc, msm->cache);
  435. lut = msm->cache = __glCreateSpecLUT(gc, exponent);
  436. #ifdef NT
  437. if (lut)
  438. {
  439. msm->threshold = lut->threshold;
  440. msm->scale = lut->scale;
  441. msm->specTable = lut->table;
  442. }
  443. else
  444. {
  445. msm->threshold = (GLfloat) 0.0;
  446. msm->scale = (GLfloat) __GL_SPEC_LOOKUP_TABLE_SIZE;
  447. msm->specTable = NULL;
  448. }
  449. #else
  450. msm->threshold = lut->threshold;
  451. msm->scale = lut->scale;
  452. msm->specTable = lut->table;
  453. #endif // NT
  454. }
  455. #ifdef NT
  456. /* Compute invariant scene color */
  457. if (changeBits & (__GL_MATERIAL_EMISSIVE | __GL_MATERIAL_AMBIENT))
  458. {
  459. if (msm->colorMaterialChange & __GL_MATERIAL_EMISSIVE)
  460. {
  461. msm->paSceneColor.r = ms->ambient.r * gc->state.light.model.ambient.r;
  462. msm->paSceneColor.g = ms->ambient.g * gc->state.light.model.ambient.g;
  463. msm->paSceneColor.b = ms->ambient.b * gc->state.light.model.ambient.b;
  464. }
  465. else if (msm->colorMaterialChange & __GL_MATERIAL_AMBIENT)
  466. {
  467. msm->paSceneColor.r = ms->emissive.r;
  468. msm->paSceneColor.g = ms->emissive.g;
  469. msm->paSceneColor.b = ms->emissive.b;
  470. }
  471. else
  472. {
  473. // there is no color material but need to compute this anyway!
  474. msm->paSceneColor.r = ms->emissive.r
  475. + ms->ambient.r * gc->state.light.model.ambient.r;
  476. msm->paSceneColor.g = ms->emissive.g
  477. + ms->ambient.g * gc->state.light.model.ambient.g;
  478. msm->paSceneColor.b = ms->emissive.b
  479. + ms->ambient.b * gc->state.light.model.ambient.b;
  480. }
  481. }
  482. #else
  483. /* Compute scene color */
  484. if (changeBits & (__GL_MATERIAL_EMISSIVE | __GL_MATERIAL_AMBIENT)) {
  485. msm->sceneColor.r = ms->emissive.r
  486. + ms->ambient.r * gc->state.light.model.ambient.r;
  487. msm->sceneColor.g = ms->emissive.g
  488. + ms->ambient.g * gc->state.light.model.ambient.g;
  489. msm->sceneColor.b = ms->emissive.b
  490. + ms->ambient.b * gc->state.light.model.ambient.b;
  491. }
  492. #endif
  493. /* Clamp material alpha */
  494. if (changeBits & __GL_MATERIAL_DIFFUSE) {
  495. msm->alpha = ms->diffuse.a * gc->alphaVertexScale;
  496. if (msm->alpha < __glZero) {
  497. msm->alpha = __glZero;
  498. } else if (msm->alpha > gc->alphaVertexScale) {
  499. msm->alpha = gc->alphaVertexScale;
  500. }
  501. }
  502. }
  503. /*
  504. ** DEPENDENCIES:
  505. **
  506. ** Derived state:
  507. **
  508. ** Enables LIGHTx
  509. ** Lightx DIFFUSE, AMBIENT, SPECULAR, POSITION, SPOT_EXPONENT,
  510. ** SPOT_CUTOFF, CONSTANT_ATTENUATION, LINEAR_ATTENUATION,
  511. ** QUADRATIC_ATTENUATION
  512. ** Light Model LOCAL_VIEWER
  513. */
  514. /*
  515. ** Compute any derived state for the enabled lights.
  516. */
  517. void FASTCALL ComputeLightState(__GLcontext *gc)
  518. {
  519. __GLlightSourceState *lss;
  520. __GLlightSourceMachine *lsm, **lsmp;
  521. __GLfloat zero;
  522. GLuint enables;
  523. GLint i;
  524. __GLspecLUTEntry *lut;
  525. zero = __glZero;
  526. lss = &gc->state.light.source[0];
  527. lsm = &gc->light.source[0];
  528. lsmp = &gc->light.sources;
  529. enables = gc->state.enables.lights;
  530. for (i = 0; i < gc->constants.numberOfLights;
  531. i++, lss++, lsm++, enables >>= 1) {
  532. if (!(enables & 1)) continue;
  533. /* Link this enabled light on to the list */
  534. *lsmp = lsm;
  535. lsm->state = lss; /* Could be done once, elsewhere... */
  536. lsmp = &lsm->next;
  537. /*
  538. ** Compute per-light derived state that wasn't already done
  539. ** in the api handlers.
  540. */
  541. lsm->position = lss->positionEye;
  542. lsm->isSpot = lss->spotLightCutOffAngle != 180;
  543. if (lsm->isSpot) {
  544. lsm->cosCutOffAngle =
  545. __GL_COSF(lss->spotLightCutOffAngle * __glDegreesToRadians);
  546. }
  547. if (lsm->isSpot && (!lsm->cache ||
  548. (lsm->spotLightExponent != lss->spotLightExponent))) {
  549. GLdouble exponent;
  550. /*
  551. ** Compute spot light exponent lookup table, but only when
  552. ** the exponent changes value and the light is a spot light.
  553. */
  554. exponent = lsm->spotLightExponent = lss->spotLightExponent;
  555. if (lsm->cache) {
  556. __glFreeSpecLUT(gc, lsm->cache);
  557. }
  558. lut = lsm->cache = __glCreateSpecLUT(gc, exponent);
  559. #ifdef NT
  560. if (lut)
  561. {
  562. lsm->threshold = lut->threshold;
  563. lsm->scale = lut->scale;
  564. lsm->spotTable = lut->table;
  565. }
  566. else
  567. {
  568. lsm->threshold = (GLfloat) 0.0;
  569. lsm->scale = (GLfloat) __GL_SPEC_LOOKUP_TABLE_SIZE;
  570. lsm->spotTable = NULL;
  571. }
  572. #else
  573. lsm->threshold = lut->threshold;
  574. lsm->scale = lut->scale;
  575. lsm->spotTable = lut->table;
  576. #endif // NT
  577. }
  578. lsm->constantAttenuation = lss->constantAttenuation;
  579. if (__GL_FLOAT_NEZ(lsm->constantAttenuation))
  580. lsm->attenuation = __glOne / lss->constantAttenuation;
  581. else
  582. lsm->attenuation = __glOne;
  583. lsm->linearAttenuation = lss->linearAttenuation;
  584. lsm->quadraticAttenuation = lss->quadraticAttenuation;
  585. /*
  586. ** Pick per-light calculation proc based on the state
  587. ** of the light source
  588. */
  589. if (gc->modes.colorIndexMode) {
  590. lsm->sli = ((__GLfloat) 0.30) * lss->specular.r
  591. + ((__GLfloat) 0.59) * lss->specular.g
  592. + ((__GLfloat) 0.11) * lss->specular.b;
  593. lsm->dli = ((__GLfloat) 0.30) * lss->diffuse.r
  594. + ((__GLfloat) 0.59) * lss->diffuse.g
  595. + ((__GLfloat) 0.11) * lss->diffuse.b;
  596. }
  597. if (!gc->state.light.model.localViewer && !lsm->isSpot
  598. && (lsm->position.w == zero)) {
  599. __GLfloat hv[3];
  600. /* Compute unit h[i] (normalized) */
  601. __glNormalize(hv, &lsm->position.x);
  602. lsm->unitVPpli.x = hv[0];
  603. lsm->unitVPpli.y = hv[1];
  604. lsm->unitVPpli.z = hv[2];
  605. hv[2] += __glOne;
  606. __glNormalize(&lsm->hHat.x, hv);
  607. lsm->slowPath = GL_FALSE;
  608. } else {
  609. lsm->slowPath = GL_TRUE;
  610. }
  611. }
  612. *lsmp = 0;
  613. }
  614. /*
  615. ** DEPENDENCIES:
  616. **
  617. ** Procs:
  618. **
  619. ** Light Model LOCAL_VIEWER
  620. ** Lightx SPOT_CUTOFF, POSITION
  621. ** Enables LIGHTING
  622. ** modeFlags CHEAP_FOG
  623. */
  624. void FASTCALL ComputeLightProcs(__GLcontext *gc)
  625. {
  626. GLboolean anySlow = GL_FALSE;
  627. __GLlightSourceMachine *lsm;
  628. for (lsm = gc->light.sources; lsm; lsm = lsm->next) {
  629. if (lsm->slowPath) {
  630. anySlow = GL_TRUE;
  631. break;
  632. }
  633. }
  634. #ifdef NT
  635. if ((gc->polygon.shader.modeFlags & __GL_SHADE_CHEAP_FOG) &&
  636. (gc->polygon.shader.modeFlags & __GL_SHADE_SMOOTH_LIGHT) &&
  637. gc->renderMode == GL_RENDER)
  638. {
  639. if (gc->modes.colorIndexMode)
  640. gc->procs.paApplyCheapFog = PolyArrayCheapFogCIColor;
  641. else
  642. gc->procs.paApplyCheapFog = PolyArrayCheapFogRGBColor;
  643. }
  644. else
  645. gc->procs.paApplyCheapFog = 0; // for debugging
  646. if (gc->state.enables.general & __GL_LIGHTING_ENABLE)
  647. {
  648. #ifdef GL_WIN_phong_shading
  649. if (gc->state.light.shadingModel == GL_PHONG_WIN)
  650. {
  651. __glGenericPickPhongProcs (gc);
  652. }
  653. //else
  654. #endif //GL_WIN_phong_shading
  655. if (gc->modes.colorIndexMode)
  656. {
  657. if (!anySlow)
  658. gc->procs.paCalcColor = PolyArrayFastCalcCIColor;
  659. else
  660. gc->procs.paCalcColor = PolyArrayCalcCIColor;
  661. }
  662. else
  663. {
  664. if (!anySlow)
  665. {
  666. // If there are no color material changes in front and back
  667. // faces, use the zippy function!
  668. if (!gc->light.front.colorMaterialChange
  669. && !gc->light.back.colorMaterialChange)
  670. gc->procs.paCalcColor = PolyArrayZippyCalcRGBColor;
  671. else
  672. gc->procs.paCalcColor = PolyArrayFastCalcRGBColor;
  673. }
  674. else
  675. {
  676. gc->procs.paCalcColor = PolyArrayCalcRGBColor;
  677. }
  678. }
  679. }
  680. else
  681. {
  682. // set it to NULL for debugging
  683. gc->procs.paCalcColor = (PFN_POLYARRAYCALCCOLOR) NULL;
  684. }
  685. if (gc->modes.colorIndexMode)
  686. gc->procs.paCalcColorSkip = PolyArrayFillIndex0;
  687. else
  688. gc->procs.paCalcColorSkip = PolyArrayFillColor0;
  689. #else
  690. if (gc->state.enables.general & __GL_LIGHTING_ENABLE) {
  691. if (gc->modes.colorIndexMode) {
  692. if (!anySlow) {
  693. gc->procs.calcColor = __glFastCalcCIColor;
  694. } else {
  695. gc->procs.calcColor = __glCalcCIColor;
  696. }
  697. } else {
  698. if (!anySlow) {
  699. gc->procs.calcColor = __glFastCalcRGBColor;
  700. } else {
  701. gc->procs.calcColor = __glCalcRGBColor;
  702. }
  703. }
  704. gc->procs.calcRasterColor = gc->procs.calcColor;
  705. if ((gc->polygon.shader.modeFlags & __GL_SHADE_CHEAP_FOG) &&
  706. (gc->polygon.shader.modeFlags & __GL_SHADE_SMOOTH_LIGHT) &&
  707. gc->renderMode == GL_RENDER) {
  708. gc->procs.calcColor2 = gc->procs.calcColor;
  709. if (gc->modes.colorIndexMode) {
  710. gc->procs.calcColor = __glFogLitCIColor;
  711. } else {
  712. gc->procs.calcColor = __glFogLitRGBColor;
  713. }
  714. }
  715. } else {
  716. gc->procs.calcRasterColor = __glNopLight;
  717. if ((gc->polygon.shader.modeFlags & __GL_SHADE_CHEAP_FOG) &&
  718. (gc->polygon.shader.modeFlags & __GL_SHADE_SMOOTH_LIGHT) &&
  719. gc->renderMode == GL_RENDER) {
  720. if (gc->modes.colorIndexMode) {
  721. gc->procs.calcColor = __glFogCIColor;
  722. } else {
  723. gc->procs.calcColor = __glFogRGBColor;
  724. }
  725. } else {
  726. gc->procs.calcColor = __glNopLight;
  727. }
  728. }
  729. #endif
  730. }
  731. /*
  732. ** DEPENDENCIES:
  733. **
  734. ** Material AMBIENT, DIFFUSE, SPECULAR
  735. ** Lightx AMBIENT, DIFFUSE, SPECULAR
  736. */
  737. void FASTCALL ComputeLightMaterialState(__GLcontext *gc, GLint frontChange,
  738. GLint backChange)
  739. {
  740. __GLmaterialState *front, *back;
  741. __GLlightSourceMachine *lsm;
  742. __GLlightSourceState *lss;
  743. __GLfloat r, g, b;
  744. GLint allChange;
  745. allChange = frontChange | backChange;
  746. if ((allChange & (__GL_MATERIAL_AMBIENT | __GL_MATERIAL_DIFFUSE |
  747. __GL_MATERIAL_SPECULAR)) == 0) {
  748. return;
  749. }
  750. front = &gc->state.light.front;
  751. back = &gc->state.light.back;
  752. for (lsm = gc->light.sources; lsm; lsm = lsm->next) {
  753. lss = lsm->state;
  754. /*
  755. ** Pre-multiply and the front & back ambient, diffuse and
  756. ** specular colors
  757. */
  758. if (allChange & __GL_MATERIAL_AMBIENT) {
  759. r = lss->ambient.r;
  760. g = lss->ambient.g;
  761. b = lss->ambient.b;
  762. if (frontChange & __GL_MATERIAL_AMBIENT) {
  763. lsm->front.ambient.r = front->ambient.r * r;
  764. lsm->front.ambient.g = front->ambient.g * g;
  765. lsm->front.ambient.b = front->ambient.b * b;
  766. }
  767. if (backChange & __GL_MATERIAL_AMBIENT) {
  768. lsm->back.ambient.r = back->ambient.r * r;
  769. lsm->back.ambient.g = back->ambient.g * g;
  770. lsm->back.ambient.b = back->ambient.b * b;
  771. }
  772. }
  773. if (allChange & __GL_MATERIAL_DIFFUSE) {
  774. r = lss->diffuse.r;
  775. g = lss->diffuse.g;
  776. b = lss->diffuse.b;
  777. if (frontChange & __GL_MATERIAL_DIFFUSE) {
  778. lsm->front.diffuse.r = front->diffuse.r * r;
  779. lsm->front.diffuse.g = front->diffuse.g * g;
  780. lsm->front.diffuse.b = front->diffuse.b * b;
  781. }
  782. if (backChange & __GL_MATERIAL_DIFFUSE) {
  783. lsm->back.diffuse.r = back->diffuse.r * r;
  784. lsm->back.diffuse.g = back->diffuse.g * g;
  785. lsm->back.diffuse.b = back->diffuse.b * b;
  786. }
  787. }
  788. if (allChange & __GL_MATERIAL_SPECULAR) {
  789. r = lss->specular.r;
  790. g = lss->specular.g;
  791. b = lss->specular.b;
  792. if (frontChange & __GL_MATERIAL_SPECULAR) {
  793. lsm->front.specular.r = front->specular.r * r;
  794. lsm->front.specular.g = front->specular.g * g;
  795. lsm->front.specular.b = front->specular.b * b;
  796. }
  797. if (backChange & __GL_MATERIAL_SPECULAR) {
  798. lsm->back.specular.r = back->specular.r * r;
  799. lsm->back.specular.g = back->specular.g * g;
  800. lsm->back.specular.b = back->specular.b * b;
  801. }
  802. }
  803. }
  804. }
  805. /*
  806. ** DEPENDENCIES:
  807. **
  808. ** Material EMISSIVE, AMBIENT, DIFFUSE, SHININESS, SPECULAR
  809. ** Light Model AMBIENT
  810. ** Lightx AMBIENT, DIFFUSE, SPECULAR
  811. */
  812. /*
  813. ** Recompute light state based upon the material change indicated by
  814. ** frontChange and backChange.
  815. */
  816. void FASTCALL __glValidateMaterial(__GLcontext *gc, GLint frontChange, GLint backChange)
  817. {
  818. ComputeMaterialState(gc, &gc->state.light.front, &gc->light.front,
  819. frontChange);
  820. ComputeMaterialState(gc, &gc->state.light.back, &gc->light.back,
  821. backChange);
  822. ComputeLightMaterialState(gc, frontChange, backChange);
  823. }
  824. /*
  825. ** DEPENDENCIES:
  826. **
  827. ** Enables LIGHTx, LIGHTING
  828. ** ( Material EMISSIVE, AMBIENT, DIFFUSE, SHININESS, SPECULAR )
  829. ** Light Model AMBIENT, LOCAL_VIEWER
  830. ** Lightx DIFFUSE, AMBIENT, SPECULAR, POSITION, SPOT_EXPONENT,
  831. ** SPOT_CUTOFF, CONSTANT_ATTENUATION, LINEAR_ATTENUATION,
  832. ** QUADRATIC_ATTENUATION
  833. ** modeFlags CHEAP_FOG
  834. */
  835. /*
  836. ** Pre-compute lighting state.
  837. */
  838. void FASTCALL __glValidateLighting(__GLcontext *gc)
  839. {
  840. if (gc->dirtyMask & __GL_DIRTY_LIGHTING) {
  841. ComputeLightState(gc);
  842. ComputeLightProcs(gc);
  843. __glValidateMaterial(gc, __GL_MATERIAL_ALL, __GL_MATERIAL_ALL);
  844. } else {
  845. ComputeLightProcs(gc);
  846. }
  847. }
  848. void FASTCALL __glGenericPickColorMaterialProcs(__GLcontext *gc)
  849. {
  850. if (gc->modes.rgbMode) {
  851. if (gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE) {
  852. switch (gc->state.light.colorMaterialFace) {
  853. case GL_FRONT_AND_BACK:
  854. gc->procs.applyColor = __glChangeBothMaterialColors;
  855. gc->light.cm = 0;
  856. gc->light.cmm = 0;
  857. break;
  858. case GL_FRONT:
  859. gc->procs.applyColor = __glChangeOneMaterialColor;
  860. gc->light.cm = &gc->state.light.front;
  861. gc->light.cmm = &gc->light.front;
  862. break;
  863. case GL_BACK:
  864. gc->procs.applyColor = __glChangeOneMaterialColor;
  865. gc->light.cm = &gc->state.light.back;
  866. gc->light.cmm = &gc->light.back;
  867. break;
  868. }
  869. switch (gc->state.light.colorMaterialParam) {
  870. case GL_EMISSION:
  871. gc->procs.changeMaterial = ChangeMaterialEmission;
  872. break;
  873. case GL_SPECULAR:
  874. gc->procs.changeMaterial = ChangeMaterialSpecular;
  875. break;
  876. case GL_AMBIENT:
  877. gc->procs.changeMaterial = ChangeMaterialAmbient;
  878. break;
  879. case GL_DIFFUSE:
  880. gc->procs.changeMaterial = ChangeMaterialDiffuse;
  881. break;
  882. case GL_AMBIENT_AND_DIFFUSE:
  883. gc->procs.changeMaterial = ChangeMaterialAmbientAndDiffuse;
  884. break;
  885. }
  886. } else {
  887. gc->procs.applyColor = __glNopGC;
  888. }
  889. } else {
  890. /*
  891. ** When in color index mode the value is copied from the
  892. ** current.userColorIndex into the vertex
  893. */
  894. gc->procs.applyColor = __glNopGC;
  895. }
  896. }