Clone of mesa.
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.

light.c 37KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285
  1. /* $Id: light.c,v 1.26 2000/11/16 21:05:35 keithw Exp $ */
  2. /*
  3. * Mesa 3-D graphics library
  4. * Version: 3.5
  5. *
  6. * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a
  9. * copy of this software and associated documentation files (the "Software"),
  10. * to deal in the Software without restriction, including without limitation
  11. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12. * and/or sell copies of the Software, and to permit persons to whom the
  13. * Software is furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included
  16. * in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21. * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  22. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. */
  25. #ifdef PC_HEADER
  26. #include "all.h"
  27. #else
  28. #include "glheader.h"
  29. #include "colormac.h"
  30. #include "context.h"
  31. #include "enums.h"
  32. #include "light.h"
  33. #include "macros.h"
  34. #include "mem.h"
  35. #include "mmath.h"
  36. #include "simple_list.h"
  37. #include "types.h"
  38. #include "math/m_xform.h"
  39. #include "math/m_matrix.h"
  40. #endif
  41. /* XXX this is a bit of a hack needed for compilation within XFree86 */
  42. #ifndef FLT_MIN
  43. #define FLT_MIN 1e-37
  44. #endif
  45. void
  46. _mesa_ShadeModel( GLenum mode )
  47. {
  48. GET_CURRENT_CONTEXT(ctx);
  49. ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glShadeModel");
  50. if (MESA_VERBOSE & VERBOSE_API)
  51. fprintf(stderr, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode));
  52. if (mode == GL_FLAT || mode == GL_SMOOTH) {
  53. if (ctx->Light.ShadeModel != mode) {
  54. ctx->Light.ShadeModel = mode;
  55. if (ctx->Light.ShadeModel == GL_FLAT)
  56. SET_BITS(ctx->_TriangleCaps, DD_FLATSHADE);
  57. else
  58. CLEAR_BITS(ctx->_TriangleCaps, DD_FLATSHADE);
  59. ctx->NewState |= _NEW_LIGHT;
  60. if (ctx->Driver.ShadeModel)
  61. (*ctx->Driver.ShadeModel)( ctx, mode );
  62. }
  63. }
  64. else {
  65. gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
  66. }
  67. }
  68. void
  69. _mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
  70. {
  71. _mesa_Lightfv( light, pname, &param );
  72. }
  73. void
  74. _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
  75. {
  76. GET_CURRENT_CONTEXT(ctx);
  77. GLint i = (GLint) (light - GL_LIGHT0);
  78. struct gl_light *l = &ctx->Light.Light[i];
  79. ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
  80. if (i < 0 || i >= MAX_LIGHTS) {
  81. gl_error( ctx, GL_INVALID_ENUM, "glLight" );
  82. return;
  83. }
  84. switch (pname) {
  85. case GL_AMBIENT:
  86. COPY_4V( l->Ambient, params );
  87. break;
  88. case GL_DIFFUSE:
  89. COPY_4V( l->Diffuse, params );
  90. break;
  91. case GL_SPECULAR:
  92. COPY_4V( l->Specular, params );
  93. break;
  94. case GL_POSITION:
  95. /* transform position by ModelView matrix */
  96. TRANSFORM_POINT( l->EyePosition, ctx->ModelView.m, params );
  97. if (l->EyePosition[3] != 0.0F)
  98. l->_Flags |= LIGHT_POSITIONAL;
  99. else
  100. l->_Flags &= ~LIGHT_POSITIONAL;
  101. break;
  102. case GL_SPOT_DIRECTION:
  103. /* transform direction by inverse modelview */
  104. if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
  105. _math_matrix_analyze( &ctx->ModelView );
  106. }
  107. TRANSFORM_NORMAL( l->EyeDirection, params, ctx->ModelView.inv );
  108. break;
  109. case GL_SPOT_EXPONENT:
  110. if (params[0]<0.0 || params[0]>128.0) {
  111. gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  112. return;
  113. }
  114. if (l->SpotExponent != params[0]) {
  115. l->SpotExponent = params[0];
  116. gl_compute_spot_exp_table( l );
  117. }
  118. break;
  119. case GL_SPOT_CUTOFF:
  120. if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
  121. gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  122. return;
  123. }
  124. l->SpotCutoff = params[0];
  125. l->_CosCutoff = cos(params[0]*DEG2RAD);
  126. if (l->_CosCutoff < 0)
  127. l->_CosCutoff = 0;
  128. if (l->SpotCutoff != 180.0F)
  129. l->_Flags |= LIGHT_SPOT;
  130. else
  131. l->_Flags &= ~LIGHT_SPOT;
  132. break;
  133. case GL_CONSTANT_ATTENUATION:
  134. if (params[0]<0.0) {
  135. gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  136. return;
  137. }
  138. l->ConstantAttenuation = params[0];
  139. break;
  140. case GL_LINEAR_ATTENUATION:
  141. if (params[0]<0.0) {
  142. gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  143. return;
  144. }
  145. l->LinearAttenuation = params[0];
  146. break;
  147. case GL_QUADRATIC_ATTENUATION:
  148. if (params[0]<0.0) {
  149. gl_error( ctx, GL_INVALID_VALUE, "glLight" );
  150. return;
  151. }
  152. l->QuadraticAttenuation = params[0];
  153. break;
  154. default:
  155. gl_error( ctx, GL_INVALID_ENUM, "glLight" );
  156. return;
  157. }
  158. if (ctx->Driver.Lightfv)
  159. ctx->Driver.Lightfv( ctx, light, pname, params );
  160. ctx->NewState |= _NEW_LIGHT;
  161. }
  162. void
  163. _mesa_Lighti( GLenum light, GLenum pname, GLint param )
  164. {
  165. _mesa_Lightiv( light, pname, &param );
  166. }
  167. void
  168. _mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
  169. {
  170. GLfloat fparam[4];
  171. switch (pname) {
  172. case GL_AMBIENT:
  173. case GL_DIFFUSE:
  174. case GL_SPECULAR:
  175. fparam[0] = INT_TO_FLOAT( params[0] );
  176. fparam[1] = INT_TO_FLOAT( params[1] );
  177. fparam[2] = INT_TO_FLOAT( params[2] );
  178. fparam[3] = INT_TO_FLOAT( params[3] );
  179. break;
  180. case GL_POSITION:
  181. fparam[0] = (GLfloat) params[0];
  182. fparam[1] = (GLfloat) params[1];
  183. fparam[2] = (GLfloat) params[2];
  184. fparam[3] = (GLfloat) params[3];
  185. break;
  186. case GL_SPOT_DIRECTION:
  187. fparam[0] = (GLfloat) params[0];
  188. fparam[1] = (GLfloat) params[1];
  189. fparam[2] = (GLfloat) params[2];
  190. break;
  191. case GL_SPOT_EXPONENT:
  192. case GL_SPOT_CUTOFF:
  193. case GL_CONSTANT_ATTENUATION:
  194. case GL_LINEAR_ATTENUATION:
  195. case GL_QUADRATIC_ATTENUATION:
  196. fparam[0] = (GLfloat) params[0];
  197. break;
  198. default:
  199. /* error will be caught later in gl_Lightfv */
  200. ;
  201. }
  202. _mesa_Lightfv( light, pname, fparam );
  203. }
  204. void
  205. _mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
  206. {
  207. GET_CURRENT_CONTEXT(ctx);
  208. GLint l = (GLint) (light - GL_LIGHT0);
  209. ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
  210. if (l<0 || l>=MAX_LIGHTS) {
  211. gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
  212. return;
  213. }
  214. switch (pname) {
  215. case GL_AMBIENT:
  216. COPY_4V( params, ctx->Light.Light[l].Ambient );
  217. break;
  218. case GL_DIFFUSE:
  219. COPY_4V( params, ctx->Light.Light[l].Diffuse );
  220. break;
  221. case GL_SPECULAR:
  222. COPY_4V( params, ctx->Light.Light[l].Specular );
  223. break;
  224. case GL_POSITION:
  225. COPY_4V( params, ctx->Light.Light[l].EyePosition );
  226. break;
  227. case GL_SPOT_DIRECTION:
  228. COPY_3V( params, ctx->Light.Light[l].EyeDirection );
  229. break;
  230. case GL_SPOT_EXPONENT:
  231. params[0] = ctx->Light.Light[l].SpotExponent;
  232. break;
  233. case GL_SPOT_CUTOFF:
  234. params[0] = ctx->Light.Light[l].SpotCutoff;
  235. break;
  236. case GL_CONSTANT_ATTENUATION:
  237. params[0] = ctx->Light.Light[l].ConstantAttenuation;
  238. break;
  239. case GL_LINEAR_ATTENUATION:
  240. params[0] = ctx->Light.Light[l].LinearAttenuation;
  241. break;
  242. case GL_QUADRATIC_ATTENUATION:
  243. params[0] = ctx->Light.Light[l].QuadraticAttenuation;
  244. break;
  245. default:
  246. gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
  247. break;
  248. }
  249. }
  250. void
  251. _mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
  252. {
  253. GET_CURRENT_CONTEXT(ctx);
  254. GLint l = (GLint) (light - GL_LIGHT0);
  255. ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
  256. if (l<0 || l>=MAX_LIGHTS) {
  257. gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
  258. return;
  259. }
  260. switch (pname) {
  261. case GL_AMBIENT:
  262. params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
  263. params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
  264. params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
  265. params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
  266. break;
  267. case GL_DIFFUSE:
  268. params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
  269. params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
  270. params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
  271. params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
  272. break;
  273. case GL_SPECULAR:
  274. params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
  275. params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
  276. params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
  277. params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
  278. break;
  279. case GL_POSITION:
  280. params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
  281. params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
  282. params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
  283. params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
  284. break;
  285. case GL_SPOT_DIRECTION:
  286. params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
  287. params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
  288. params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
  289. break;
  290. case GL_SPOT_EXPONENT:
  291. params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
  292. break;
  293. case GL_SPOT_CUTOFF:
  294. params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
  295. break;
  296. case GL_CONSTANT_ATTENUATION:
  297. params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
  298. break;
  299. case GL_LINEAR_ATTENUATION:
  300. params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
  301. break;
  302. case GL_QUADRATIC_ATTENUATION:
  303. params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
  304. break;
  305. default:
  306. gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
  307. break;
  308. }
  309. }
  310. /**********************************************************************/
  311. /*** Light Model ***/
  312. /**********************************************************************/
  313. void
  314. _mesa_LightModelfv( GLenum pname, const GLfloat *params )
  315. {
  316. GET_CURRENT_CONTEXT(ctx);
  317. ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModelfv");
  318. switch (pname) {
  319. case GL_LIGHT_MODEL_AMBIENT:
  320. COPY_4V( ctx->Light.Model.Ambient, params );
  321. break;
  322. case GL_LIGHT_MODEL_LOCAL_VIEWER:
  323. if (params[0]==0.0)
  324. ctx->Light.Model.LocalViewer = GL_FALSE;
  325. else
  326. ctx->Light.Model.LocalViewer = GL_TRUE;
  327. break;
  328. case GL_LIGHT_MODEL_TWO_SIDE:
  329. if (params[0]==0.0)
  330. ctx->Light.Model.TwoSide = GL_FALSE;
  331. else
  332. ctx->Light.Model.TwoSide = GL_TRUE;
  333. break;
  334. case GL_LIGHT_MODEL_COLOR_CONTROL:
  335. if (params[0] == (GLfloat) GL_SINGLE_COLOR) {
  336. ctx->Light.Model.ColorControl = GL_SINGLE_COLOR;
  337. if (!ctx->Fog.ColorSumEnabled)
  338. CLEAR_BITS(ctx->_TriangleCaps, DD_SEPERATE_SPECULAR);
  339. }
  340. else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) {
  341. ctx->Light.Model.ColorControl = GL_SEPARATE_SPECULAR_COLOR;
  342. SET_BITS(ctx->_TriangleCaps, DD_SEPERATE_SPECULAR);
  343. }
  344. else {
  345. gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
  346. }
  347. break;
  348. default:
  349. gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
  350. break;
  351. }
  352. if (ctx->Driver.LightModelfv)
  353. ctx->Driver.LightModelfv( ctx, pname, params );
  354. ctx->NewState |= _NEW_LIGHT;
  355. }
  356. void
  357. _mesa_LightModeliv( GLenum pname, const GLint *params )
  358. {
  359. GLfloat fparam[4];
  360. GET_CURRENT_CONTEXT(ctx);
  361. ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModeliv");
  362. switch (pname) {
  363. case GL_LIGHT_MODEL_AMBIENT:
  364. fparam[0] = INT_TO_FLOAT( params[0] );
  365. fparam[1] = INT_TO_FLOAT( params[1] );
  366. fparam[2] = INT_TO_FLOAT( params[2] );
  367. fparam[3] = INT_TO_FLOAT( params[3] );
  368. break;
  369. case GL_LIGHT_MODEL_LOCAL_VIEWER:
  370. case GL_LIGHT_MODEL_TWO_SIDE:
  371. case GL_LIGHT_MODEL_COLOR_CONTROL:
  372. fparam[0] = (GLfloat) params[0];
  373. break;
  374. default:
  375. /* Error will be caught later in gl_LightModelfv */
  376. ;
  377. }
  378. _mesa_LightModelfv( pname, fparam );
  379. }
  380. void
  381. _mesa_LightModeli( GLenum pname, GLint param )
  382. {
  383. _mesa_LightModeliv( pname, &param );
  384. }
  385. void
  386. _mesa_LightModelf( GLenum pname, GLfloat param )
  387. {
  388. _mesa_LightModelfv( pname, &param );
  389. }
  390. /********** MATERIAL **********/
  391. /*
  392. * Given a face and pname value (ala glColorMaterial), compute a bitmask
  393. * of the targeted material values.
  394. */
  395. GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,
  396. GLuint legal,
  397. const char *where )
  398. {
  399. GLuint bitmask = 0;
  400. /* Make a bitmask indicating what material attribute(s) we're updating */
  401. switch (pname) {
  402. case GL_EMISSION:
  403. bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
  404. break;
  405. case GL_AMBIENT:
  406. bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
  407. break;
  408. case GL_DIFFUSE:
  409. bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
  410. break;
  411. case GL_SPECULAR:
  412. bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
  413. break;
  414. case GL_SHININESS:
  415. bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
  416. break;
  417. case GL_AMBIENT_AND_DIFFUSE:
  418. bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
  419. bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
  420. break;
  421. case GL_COLOR_INDEXES:
  422. bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT;
  423. break;
  424. default:
  425. gl_error( ctx, GL_INVALID_ENUM, where );
  426. return 0;
  427. }
  428. if (face==GL_FRONT) {
  429. bitmask &= FRONT_MATERIAL_BITS;
  430. }
  431. else if (face==GL_BACK) {
  432. bitmask &= BACK_MATERIAL_BITS;
  433. }
  434. else if (face != GL_FRONT_AND_BACK) {
  435. gl_error( ctx, GL_INVALID_ENUM, where );
  436. return 0;
  437. }
  438. if (bitmask & ~legal) {
  439. gl_error( ctx, GL_INVALID_ENUM, where );
  440. return 0;
  441. }
  442. return bitmask;
  443. }
  444. /*
  445. * Check if the global material has to be updated with info that was
  446. * associated with a vertex via glMaterial.
  447. * This function is used when any material values get changed between
  448. * glBegin/glEnd either by calling glMaterial() or by calling glColor()
  449. * when GL_COLOR_MATERIAL is enabled.
  450. *
  451. * src[0] is front material, src[1] is back material
  452. *
  453. * KW: Added code here to keep the precomputed variables uptodate.
  454. * This means we can use the faster shade functions when using
  455. * GL_COLOR_MATERIAL, and we can also now use the precomputed
  456. * values in the slower shading functions, which further offsets
  457. * the cost of doing this here.
  458. */
  459. void gl_update_material( GLcontext *ctx,
  460. const struct gl_material src[2],
  461. GLuint bitmask )
  462. {
  463. struct gl_light *light, *list = &ctx->Light.EnabledList;
  464. if (ctx->Light.ColorMaterialEnabled)
  465. bitmask &= ~ctx->Light.ColorMaterialBitmask;
  466. if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
  467. fprintf(stderr, "gl_update_material, mask 0x%x\n", bitmask);
  468. if (!bitmask)
  469. return;
  470. /* update material emission */
  471. if (bitmask & FRONT_EMISSION_BIT) {
  472. struct gl_material *mat = &ctx->Light.Material[0];
  473. COPY_4FV( mat->Emission, src[0].Emission );
  474. }
  475. if (bitmask & BACK_EMISSION_BIT) {
  476. struct gl_material *mat = &ctx->Light.Material[1];
  477. COPY_4FV( mat->Emission, src[1].Emission );
  478. }
  479. /* update material ambience */
  480. if (bitmask & FRONT_AMBIENT_BIT) {
  481. struct gl_material *mat = &ctx->Light.Material[0];
  482. COPY_4FV( mat->Ambient, src[0].Ambient );
  483. foreach (light, list) {
  484. SCALE_3V( light->_MatAmbient[0], light->Ambient, src[0].Ambient);
  485. }
  486. }
  487. if (bitmask & BACK_AMBIENT_BIT) {
  488. struct gl_material *mat = &ctx->Light.Material[1];
  489. COPY_4FV( mat->Ambient, src[1].Ambient );
  490. foreach (light, list) {
  491. SCALE_3V( light->_MatAmbient[1], light->Ambient, src[1].Ambient);
  492. }
  493. }
  494. /* update BaseColor = emission + scene's ambience * material's ambience */
  495. if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
  496. struct gl_material *mat = &ctx->Light.Material[0];
  497. COPY_3V( ctx->Light._BaseColor[0], mat->Emission );
  498. ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient );
  499. }
  500. if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
  501. struct gl_material *mat = &ctx->Light.Material[1];
  502. COPY_3V( ctx->Light._BaseColor[1], mat->Emission );
  503. ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient );
  504. }
  505. /* update material diffuse values */
  506. if (bitmask & FRONT_DIFFUSE_BIT) {
  507. struct gl_material *mat = &ctx->Light.Material[0];
  508. GLfloat tmp[4];
  509. SUB_3V( tmp, src[0].Diffuse, mat->Diffuse );
  510. foreach (light, list) {
  511. ACC_SCALE_3V( light->_MatDiffuse[0], light->Diffuse, tmp );
  512. }
  513. COPY_4FV( mat->Diffuse, src[0].Diffuse );
  514. FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[0], mat->Diffuse[3]);
  515. }
  516. if (bitmask & BACK_DIFFUSE_BIT) {
  517. struct gl_material *mat = &ctx->Light.Material[1];
  518. GLfloat tmp[4];
  519. SUB_3V( tmp, src[1].Diffuse, mat->Diffuse );
  520. foreach (light, list) {
  521. ACC_SCALE_3V( light->_MatDiffuse[1], light->Diffuse, tmp );
  522. }
  523. COPY_4FV( mat->Diffuse, src[1].Diffuse );
  524. FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[1], mat->Diffuse[3]);
  525. }
  526. /* update material specular values */
  527. if (bitmask & FRONT_SPECULAR_BIT) {
  528. struct gl_material *mat = &ctx->Light.Material[0];
  529. GLfloat tmp[4];
  530. SUB_3V( tmp, src[0].Specular, mat->Specular );
  531. foreach (light, list) {
  532. ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp );
  533. light->_IsMatSpecular[0] =
  534. (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16);
  535. }
  536. COPY_4FV( mat->Specular, src[0].Specular );
  537. }
  538. if (bitmask & BACK_SPECULAR_BIT) {
  539. struct gl_material *mat = &ctx->Light.Material[1];
  540. GLfloat tmp[4];
  541. SUB_3V( tmp, src[1].Specular, mat->Specular );
  542. foreach (light, list) {
  543. ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp );
  544. light->_IsMatSpecular[1] =
  545. (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16);
  546. }
  547. COPY_4FV( mat->Specular, src[1].Specular );
  548. }
  549. if (bitmask & FRONT_SHININESS_BIT) {
  550. GLfloat shininess = ctx->Light.Material[0].Shininess = src[0].Shininess;
  551. gl_compute_shine_table( ctx, 0, shininess );
  552. gl_compute_shine_table( ctx, 2, shininess * .5 );
  553. }
  554. if (bitmask & BACK_SHININESS_BIT) {
  555. GLfloat shininess = ctx->Light.Material[1].Shininess = src[1].Shininess;
  556. gl_compute_shine_table( ctx, 1, shininess );
  557. gl_compute_shine_table( ctx, 3, shininess * .5 );
  558. }
  559. if (bitmask & FRONT_INDEXES_BIT) {
  560. ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex;
  561. ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex;
  562. ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex;
  563. }
  564. if (bitmask & BACK_INDEXES_BIT) {
  565. ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex;
  566. ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex;
  567. ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
  568. }
  569. if (0)
  570. {
  571. struct gl_material *mat = &ctx->Light.Material[0];
  572. fprintf(stderr, "update_mat emission : %f %f %f\n",
  573. mat->Emission[0],
  574. mat->Emission[1],
  575. mat->Emission[2]);
  576. fprintf(stderr, "update_mat specular : %f %f %f\n",
  577. mat->Specular[0],
  578. mat->Specular[1],
  579. mat->Specular[2]);
  580. fprintf(stderr, "update_mat diffuse : %f %f %f\n",
  581. mat->Diffuse[0],
  582. mat->Diffuse[1],
  583. mat->Diffuse[2]);
  584. fprintf(stderr, "update_mat ambient : %f %f %f\n",
  585. mat->Ambient[0],
  586. mat->Ambient[1],
  587. mat->Ambient[2]);
  588. }
  589. }
  590. /*
  591. * Update the current materials from the given rgba color
  592. * according to the bitmask in ColorMaterialBitmask, which is
  593. * set by glColorMaterial().
  594. */
  595. void gl_update_color_material( GLcontext *ctx,
  596. const GLchan rgba[4] )
  597. {
  598. struct gl_light *light, *list = &ctx->Light.EnabledList;
  599. GLuint bitmask = ctx->Light.ColorMaterialBitmask;
  600. GLfloat color[4];
  601. color[0] = CHAN_TO_FLOAT(rgba[0]);
  602. color[1] = CHAN_TO_FLOAT(rgba[1]);
  603. color[2] = CHAN_TO_FLOAT(rgba[2]);
  604. color[3] = CHAN_TO_FLOAT(rgba[3]);
  605. if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
  606. fprintf(stderr, "gl_update_color_material, mask 0x%x\n", bitmask);
  607. /* update emissive colors */
  608. if (bitmask & FRONT_EMISSION_BIT) {
  609. struct gl_material *mat = &ctx->Light.Material[0];
  610. COPY_4FV( mat->Emission, color );
  611. }
  612. if (bitmask & BACK_EMISSION_BIT) {
  613. struct gl_material *mat = &ctx->Light.Material[1];
  614. COPY_4FV( mat->Emission, color );
  615. }
  616. /* update light->_MatAmbient = light's ambient * material's ambient */
  617. if (bitmask & FRONT_AMBIENT_BIT) {
  618. struct gl_material *mat = &ctx->Light.Material[0];
  619. foreach (light, list) {
  620. SCALE_3V( light->_MatAmbient[0], light->Ambient, color);
  621. }
  622. COPY_4FV( mat->Ambient, color );
  623. }
  624. if (bitmask & BACK_AMBIENT_BIT) {
  625. struct gl_material *mat = &ctx->Light.Material[1];
  626. foreach (light, list) {
  627. SCALE_3V( light->_MatAmbient[1], light->Ambient, color);
  628. }
  629. COPY_4FV( mat->Ambient, color );
  630. }
  631. /* update BaseColor = emission + scene's ambience * material's ambience */
  632. if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
  633. struct gl_material *mat = &ctx->Light.Material[0];
  634. COPY_3V( ctx->Light._BaseColor[0], mat->Emission );
  635. ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient );
  636. }
  637. if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
  638. struct gl_material *mat = &ctx->Light.Material[1];
  639. COPY_3V( ctx->Light._BaseColor[1], mat->Emission );
  640. ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient );
  641. }
  642. /* update light->_MatDiffuse = light's diffuse * material's diffuse */
  643. if (bitmask & FRONT_DIFFUSE_BIT) {
  644. struct gl_material *mat = &ctx->Light.Material[0];
  645. GLfloat tmp[4];
  646. SUB_3V( tmp, color, mat->Diffuse );
  647. foreach (light, list) {
  648. ACC_SCALE_3V( light->_MatDiffuse[0], light->Diffuse, tmp );
  649. }
  650. COPY_4FV( mat->Diffuse, color );
  651. FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[0], mat->Diffuse[3]);
  652. }
  653. if (bitmask & BACK_DIFFUSE_BIT) {
  654. struct gl_material *mat = &ctx->Light.Material[1];
  655. GLfloat tmp[4];
  656. SUB_3V( tmp, color, mat->Diffuse );
  657. foreach (light, list) {
  658. ACC_SCALE_3V( light->_MatDiffuse[1], light->Diffuse, tmp );
  659. }
  660. COPY_4FV( mat->Diffuse, color );
  661. FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[1], mat->Diffuse[3]);
  662. }
  663. /* update light->_MatSpecular = light's specular * material's specular */
  664. if (bitmask & FRONT_SPECULAR_BIT) {
  665. struct gl_material *mat = &ctx->Light.Material[0];
  666. GLfloat tmp[4];
  667. SUB_3V( tmp, color, mat->Specular );
  668. foreach (light, list) {
  669. ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp );
  670. light->_IsMatSpecular[0] =
  671. (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16);
  672. }
  673. COPY_4FV( mat->Specular, color );
  674. }
  675. if (bitmask & BACK_SPECULAR_BIT) {
  676. struct gl_material *mat = &ctx->Light.Material[1];
  677. GLfloat tmp[4];
  678. SUB_3V( tmp, color, mat->Specular );
  679. foreach (light, list) {
  680. ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp );
  681. light->_IsMatSpecular[1] =
  682. (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16);
  683. }
  684. COPY_4FV( mat->Specular, color );
  685. }
  686. if (0)
  687. {
  688. struct gl_material *mat = &ctx->Light.Material[0];
  689. fprintf(stderr, "update_color_mat emission : %f %f %f\n",
  690. mat->Emission[0],
  691. mat->Emission[1],
  692. mat->Emission[2]);
  693. fprintf(stderr, "update_color_mat specular : %f %f %f\n",
  694. mat->Specular[0],
  695. mat->Specular[1],
  696. mat->Specular[2]);
  697. fprintf(stderr, "update_color_mat diffuse : %f %f %f\n",
  698. mat->Diffuse[0],
  699. mat->Diffuse[1],
  700. mat->Diffuse[2]);
  701. fprintf(stderr, "update_color_mat ambient : %f %f %f\n",
  702. mat->Ambient[0],
  703. mat->Ambient[1],
  704. mat->Ambient[2]);
  705. }
  706. }
  707. void
  708. _mesa_ColorMaterial( GLenum face, GLenum mode )
  709. {
  710. GET_CURRENT_CONTEXT(ctx);
  711. GLuint bitmask;
  712. GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
  713. FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
  714. FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT |
  715. FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT);
  716. ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
  717. if (MESA_VERBOSE&VERBOSE_API)
  718. fprintf(stderr, "glColorMaterial %s %s\n",
  719. gl_lookup_enum_by_nr(face),
  720. gl_lookup_enum_by_nr(mode));
  721. bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
  722. if (bitmask != 0) {
  723. ctx->Light.ColorMaterialBitmask = bitmask;
  724. ctx->Light.ColorMaterialFace = face;
  725. ctx->Light.ColorMaterialMode = mode;
  726. }
  727. if (ctx->Light.ColorMaterialEnabled) {
  728. FLUSH_TNL( ctx, FLUSH_UPDATE_CURRENT );
  729. gl_update_color_material( ctx, ctx->Current.Color );
  730. }
  731. ctx->NewState |= _NEW_LIGHT;
  732. }
  733. void
  734. _mesa_Materialf( GLenum face, GLenum pname, GLfloat param )
  735. {
  736. _mesa_Materialfv( face, pname, &param );
  737. }
  738. void
  739. _mesa_Materiali(GLenum face, GLenum pname, GLint param )
  740. {
  741. _mesa_Materialiv(face, pname, &param);
  742. }
  743. void
  744. _mesa_Materialiv(GLenum face, GLenum pname, const GLint *params )
  745. {
  746. GLfloat fparam[4];
  747. switch (pname) {
  748. case GL_AMBIENT:
  749. case GL_DIFFUSE:
  750. case GL_SPECULAR:
  751. case GL_EMISSION:
  752. case GL_AMBIENT_AND_DIFFUSE:
  753. fparam[0] = INT_TO_FLOAT( params[0] );
  754. fparam[1] = INT_TO_FLOAT( params[1] );
  755. fparam[2] = INT_TO_FLOAT( params[2] );
  756. fparam[3] = INT_TO_FLOAT( params[3] );
  757. break;
  758. case GL_SHININESS:
  759. fparam[0] = (GLfloat) params[0];
  760. break;
  761. case GL_COLOR_INDEXES:
  762. fparam[0] = (GLfloat) params[0];
  763. fparam[1] = (GLfloat) params[1];
  764. fparam[2] = (GLfloat) params[2];
  765. break;
  766. default:
  767. /* Error will be caught later in gl_Materialfv */
  768. ;
  769. }
  770. _mesa_Materialfv(face, pname, fparam);
  771. }
  772. void
  773. _mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
  774. {
  775. GET_CURRENT_CONTEXT(ctx);
  776. GLuint f;
  777. ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
  778. if (face==GL_FRONT) {
  779. f = 0;
  780. }
  781. else if (face==GL_BACK) {
  782. f = 1;
  783. }
  784. else {
  785. gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
  786. return;
  787. }
  788. switch (pname) {
  789. case GL_AMBIENT:
  790. COPY_4FV( params, ctx->Light.Material[f].Ambient );
  791. break;
  792. case GL_DIFFUSE:
  793. COPY_4FV( params, ctx->Light.Material[f].Diffuse );
  794. break;
  795. case GL_SPECULAR:
  796. COPY_4FV( params, ctx->Light.Material[f].Specular );
  797. break;
  798. case GL_EMISSION:
  799. COPY_4FV( params, ctx->Light.Material[f].Emission );
  800. break;
  801. case GL_SHININESS:
  802. *params = ctx->Light.Material[f].Shininess;
  803. break;
  804. case GL_COLOR_INDEXES:
  805. params[0] = ctx->Light.Material[f].AmbientIndex;
  806. params[1] = ctx->Light.Material[f].DiffuseIndex;
  807. params[2] = ctx->Light.Material[f].SpecularIndex;
  808. break;
  809. default:
  810. gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
  811. }
  812. }
  813. void
  814. _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
  815. {
  816. GET_CURRENT_CONTEXT(ctx);
  817. GLuint f;
  818. ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
  819. if (face==GL_FRONT) {
  820. f = 0;
  821. }
  822. else if (face==GL_BACK) {
  823. f = 1;
  824. }
  825. else {
  826. gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
  827. return;
  828. }
  829. switch (pname) {
  830. case GL_AMBIENT:
  831. params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
  832. params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
  833. params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
  834. params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
  835. break;
  836. case GL_DIFFUSE:
  837. params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
  838. params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
  839. params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
  840. params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
  841. break;
  842. case GL_SPECULAR:
  843. params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
  844. params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
  845. params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
  846. params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
  847. break;
  848. case GL_EMISSION:
  849. params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
  850. params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
  851. params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
  852. params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
  853. break;
  854. case GL_SHININESS:
  855. *params = ROUNDF( ctx->Light.Material[f].Shininess );
  856. break;
  857. case GL_COLOR_INDEXES:
  858. params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
  859. params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
  860. params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
  861. break;
  862. default:
  863. gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
  864. }
  865. }
  866. /**********************************************************************/
  867. /***** Lighting computation *****/
  868. /**********************************************************************/
  869. /*
  870. * Notes:
  871. * When two-sided lighting is enabled we compute the color (or index)
  872. * for both the front and back side of the primitive. Then, when the
  873. * orientation of the facet is later learned, we can determine which
  874. * color (or index) to use for rendering.
  875. *
  876. * KW: We now know orientation in advance and only shade for
  877. * the side or sides which are actually required.
  878. *
  879. * Variables:
  880. * n = normal vector
  881. * V = vertex position
  882. * P = light source position
  883. * Pe = (0,0,0,1)
  884. *
  885. * Precomputed:
  886. * IF P[3]==0 THEN
  887. * // light at infinity
  888. * IF local_viewer THEN
  889. * _VP_inf_norm = unit vector from V to P // Precompute
  890. * ELSE
  891. * // eye at infinity
  892. * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
  893. * ENDIF
  894. * ENDIF
  895. *
  896. * Functions:
  897. * Normalize( v ) = normalized vector v
  898. * Magnitude( v ) = length of vector v
  899. */
  900. /*
  901. * Whenever the spotlight exponent for a light changes we must call
  902. * this function to recompute the exponent lookup table.
  903. */
  904. void
  905. gl_compute_spot_exp_table( struct gl_light *l )
  906. {
  907. GLint i;
  908. GLdouble exponent = l->SpotExponent;
  909. GLdouble tmp = 0;
  910. GLint clamp = 0;
  911. l->_SpotExpTable[0][0] = 0.0;
  912. for (i = EXP_TABLE_SIZE - 1; i > 0 ;i--) {
  913. if (clamp == 0) {
  914. tmp = pow(i / (GLdouble) (EXP_TABLE_SIZE - 1), exponent);
  915. if (tmp < FLT_MIN * 100.0) {
  916. tmp = 0.0;
  917. clamp = 1;
  918. }
  919. }
  920. l->_SpotExpTable[i][0] = tmp;
  921. }
  922. for (i = 0; i < EXP_TABLE_SIZE - 1; i++) {
  923. l->_SpotExpTable[i][1] = l->_SpotExpTable[i+1][0] - l->_SpotExpTable[i][0];
  924. }
  925. l->_SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
  926. }
  927. /* Calculate a new shine table. Doing this here saves a branch in
  928. * lighting, and the cost of doing it early may be partially offset
  929. * by keeping a MRU cache of shine tables for various shine values.
  930. */
  931. static void
  932. compute_shine_table( struct gl_shine_tab *tab, GLfloat shininess )
  933. {
  934. GLint i;
  935. GLfloat *m = tab->tab;
  936. m[0] = 0.0;
  937. if (shininess == 0.0) {
  938. for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++)
  939. m[i] = 1.0;
  940. }
  941. else {
  942. for (i = 1 ; i < SHINE_TABLE_SIZE ; i++) {
  943. GLdouble t = pow(i / (GLfloat) (SHINE_TABLE_SIZE - 1), shininess);
  944. if (t > 1e-20)
  945. m[i] = t;
  946. else
  947. m[i] = 0.0;
  948. }
  949. m[SHINE_TABLE_SIZE] = 1.0;
  950. }
  951. tab->shininess = shininess;
  952. }
  953. void
  954. gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
  955. {
  956. #define DISTSQR(a,b) ((a-b)*(a-b))
  957. struct gl_shine_tab *list = ctx->_ShineTabList;
  958. struct gl_shine_tab *s;
  959. foreach(s, list)
  960. if ( DISTSQR(s->shininess, shininess) < 1e-4 )
  961. break;
  962. if (s == list) {
  963. foreach(s, list)
  964. if (s->refcount == 0)
  965. break;
  966. compute_shine_table( s, shininess );
  967. }
  968. ctx->_ShineTable[i]->refcount--;
  969. ctx->_ShineTable[i] = s;
  970. move_to_tail( list, s );
  971. s->refcount++;
  972. #undef DISTSQR
  973. }
  974. /*
  975. * Examine current lighting parameters to determine if the optimized lighting
  976. * function can be used.
  977. * Also, precompute some lighting values such as the products of light
  978. * source and material ambient, diffuse and specular coefficients.
  979. */
  980. void
  981. gl_update_lighting( GLcontext *ctx )
  982. {
  983. struct gl_light *light;
  984. ctx->_TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
  985. ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT;
  986. ctx->_NeedNormals &= ~NEED_NORMALS_LIGHT;
  987. ctx->Light._Flags = 0;
  988. if (!ctx->Light.Enabled)
  989. return;
  990. ctx->_NeedNormals |= NEED_NORMALS_LIGHT;
  991. if (ctx->Light.Model.TwoSide)
  992. ctx->_TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
  993. foreach(light, &ctx->Light.EnabledList) {
  994. ctx->Light._Flags |= light->_Flags;
  995. }
  996. ctx->Light._NeedVertices =
  997. ((ctx->Light._Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
  998. ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
  999. ctx->Light.Model.LocalViewer);
  1000. if ((ctx->Light._Flags & LIGHT_POSITIONAL) ||
  1001. ctx->Light.Model.LocalViewer)
  1002. ctx->_NeedEyeCoords |= NEED_EYE_LIGHT;
  1003. /* XXX: This test is overkill & needs to be fixed both for software and
  1004. * hardware t&l drivers. The above should be sufficient & should
  1005. * be tested to verify this.
  1006. */
  1007. if (ctx->Light._NeedVertices)
  1008. ctx->_NeedEyeCoords |= NEED_EYE_LIGHT;
  1009. /* Precompute some shading values.
  1010. */
  1011. if (ctx->Visual.RGBAflag) {
  1012. GLuint sides = ctx->Light.Model.TwoSide ? 2 : 1;
  1013. GLuint side;
  1014. for (side=0; side < sides; side++) {
  1015. struct gl_material *mat = &ctx->Light.Material[side];
  1016. COPY_3V(ctx->Light._BaseColor[side], mat->Emission);
  1017. ACC_SCALE_3V(ctx->Light._BaseColor[side],
  1018. ctx->Light.Model.Ambient,
  1019. mat->Ambient);
  1020. FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[side],
  1021. ctx->Light.Material[side].Diffuse[3] );
  1022. }
  1023. foreach (light, &ctx->Light.EnabledList) {
  1024. for (side=0; side< sides; side++) {
  1025. const struct gl_material *mat = &ctx->Light.Material[side];
  1026. SCALE_3V( light->_MatDiffuse[side], light->Diffuse, mat->Diffuse );
  1027. SCALE_3V( light->_MatAmbient[side], light->Ambient, mat->Ambient );
  1028. SCALE_3V( light->_MatSpecular[side], light->Specular,
  1029. mat->Specular);
  1030. light->_IsMatSpecular[side] =
  1031. (LEN_SQUARED_3FV(light->_MatSpecular[side]) > 1e-16);
  1032. }
  1033. }
  1034. }
  1035. else {
  1036. static const GLfloat ci[3] = { .30, .59, .11 };
  1037. foreach(light, &ctx->Light.EnabledList) {
  1038. light->_dli = DOT3(ci, light->Diffuse);
  1039. light->_sli = DOT3(ci, light->Specular);
  1040. }
  1041. }
  1042. }
  1043. /* _NEW_MODELVIEW
  1044. * _NEW_LIGHT
  1045. * _TNL_NEW_NEED_EYE_COORDS
  1046. *
  1047. * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
  1048. * Also update on lighting space changes.
  1049. */
  1050. void
  1051. gl_compute_light_positions( GLcontext *ctx )
  1052. {
  1053. struct gl_light *light;
  1054. static const GLfloat eye_z[3] = { 0, 0, 1 };
  1055. if (!ctx->Light.Enabled)
  1056. return;
  1057. if (ctx->_NeedEyeCoords) {
  1058. COPY_3V( ctx->_EyeZDir, eye_z );
  1059. }
  1060. else {
  1061. TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelView.m );
  1062. }
  1063. foreach (light, &ctx->Light.EnabledList) {
  1064. if (ctx->_NeedEyeCoords) {
  1065. COPY_4FV( light->_Position, light->EyePosition );
  1066. }
  1067. else {
  1068. TRANSFORM_POINT( light->_Position, ctx->ModelView.inv,
  1069. light->EyePosition );
  1070. }
  1071. if (!(light->_Flags & LIGHT_POSITIONAL)) {
  1072. /* VP (VP) = Normalize( Position ) */
  1073. COPY_3V( light->_VP_inf_norm, light->_Position );
  1074. NORMALIZE_3FV( light->_VP_inf_norm );
  1075. if (!ctx->Light.Model.LocalViewer) {
  1076. /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
  1077. ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
  1078. NORMALIZE_3FV( light->_h_inf_norm );
  1079. }
  1080. light->_VP_inf_spot_attenuation = 1.0;
  1081. }
  1082. if (light->_Flags & LIGHT_SPOT) {
  1083. if (ctx->_NeedEyeCoords) {
  1084. COPY_3V( light->_NormDirection, light->EyeDirection );
  1085. }
  1086. else {
  1087. TRANSFORM_NORMAL( light->_NormDirection,
  1088. light->EyeDirection,
  1089. ctx->ModelView.m);
  1090. }
  1091. NORMALIZE_3FV( light->_NormDirection );
  1092. if (!(light->_Flags & LIGHT_POSITIONAL)) {
  1093. GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
  1094. light->_NormDirection);
  1095. if (PV_dot_dir > light->_CosCutoff) {
  1096. double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
  1097. int k = (int) x;
  1098. light->_VP_inf_spot_attenuation =
  1099. (light->_SpotExpTable[k][0] +
  1100. (x-k)*light->_SpotExpTable[k][1]);
  1101. }
  1102. else {
  1103. light->_VP_inf_spot_attenuation = 0;
  1104. }
  1105. }
  1106. }
  1107. }
  1108. }