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.

prog_statevars.c 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. /*
  2. * Mesa 3-D graphics library
  3. * Version: 6.5.3
  4. *
  5. * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included
  15. * in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. /**
  25. * \file prog_statevars.c
  26. * Program state variable management.
  27. * \author Brian Paul
  28. */
  29. #include "glheader.h"
  30. #include "context.h"
  31. #include "hash.h"
  32. #include "imports.h"
  33. #include "macros.h"
  34. #include "mtypes.h"
  35. #include "prog_statevars.h"
  36. #include "prog_parameter.h"
  37. #include "nvvertparse.h"
  38. /**
  39. * Use the list of tokens in the state[] array to find global GL state
  40. * and return it in <value>. Usually, four values are returned in <value>
  41. * but matrix queries may return as many as 16 values.
  42. * This function is used for ARB vertex/fragment programs.
  43. * The program parser will produce the state[] values.
  44. */
  45. static void
  46. _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
  47. GLfloat *value)
  48. {
  49. switch (state[0]) {
  50. case STATE_MATERIAL:
  51. {
  52. /* state[1] is either 0=front or 1=back side */
  53. const GLuint face = (GLuint) state[1];
  54. const struct gl_material *mat = &ctx->Light.Material;
  55. ASSERT(face == 0 || face == 1);
  56. /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */
  57. ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT);
  58. /* XXX we could get rid of this switch entirely with a little
  59. * work in arbprogparse.c's parse_state_single_item().
  60. */
  61. /* state[2] is the material attribute */
  62. switch (state[2]) {
  63. case STATE_AMBIENT:
  64. COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
  65. return;
  66. case STATE_DIFFUSE:
  67. COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
  68. return;
  69. case STATE_SPECULAR:
  70. COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
  71. return;
  72. case STATE_EMISSION:
  73. COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
  74. return;
  75. case STATE_SHININESS:
  76. value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
  77. value[1] = 0.0F;
  78. value[2] = 0.0F;
  79. value[3] = 1.0F;
  80. return;
  81. default:
  82. _mesa_problem(ctx, "Invalid material state in fetch_state");
  83. return;
  84. }
  85. }
  86. case STATE_LIGHT:
  87. {
  88. /* state[1] is the light number */
  89. const GLuint ln = (GLuint) state[1];
  90. /* state[2] is the light attribute */
  91. switch (state[2]) {
  92. case STATE_AMBIENT:
  93. COPY_4V(value, ctx->Light.Light[ln].Ambient);
  94. return;
  95. case STATE_DIFFUSE:
  96. COPY_4V(value, ctx->Light.Light[ln].Diffuse);
  97. return;
  98. case STATE_SPECULAR:
  99. COPY_4V(value, ctx->Light.Light[ln].Specular);
  100. return;
  101. case STATE_POSITION:
  102. COPY_4V(value, ctx->Light.Light[ln].EyePosition);
  103. return;
  104. case STATE_ATTENUATION:
  105. value[0] = ctx->Light.Light[ln].ConstantAttenuation;
  106. value[1] = ctx->Light.Light[ln].LinearAttenuation;
  107. value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
  108. value[3] = ctx->Light.Light[ln].SpotExponent;
  109. return;
  110. case STATE_SPOT_DIRECTION:
  111. COPY_3V(value, ctx->Light.Light[ln].EyeDirection);
  112. value[3] = ctx->Light.Light[ln]._CosCutoff;
  113. return;
  114. case STATE_HALF:
  115. {
  116. GLfloat eye_z[] = {0, 0, 1};
  117. /* Compute infinite half angle vector:
  118. * half-vector = light_position + (0, 0, 1)
  119. * and then normalize. w = 0
  120. *
  121. * light.EyePosition.w should be 0 for infinite lights.
  122. */
  123. ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition);
  124. NORMALIZE_3FV(value);
  125. value[3] = 0;
  126. }
  127. return;
  128. case STATE_POSITION_NORMALIZED:
  129. COPY_4V(value, ctx->Light.Light[ln].EyePosition);
  130. NORMALIZE_3FV( value );
  131. return;
  132. default:
  133. _mesa_problem(ctx, "Invalid light state in fetch_state");
  134. return;
  135. }
  136. }
  137. case STATE_LIGHTMODEL_AMBIENT:
  138. COPY_4V(value, ctx->Light.Model.Ambient);
  139. return;
  140. case STATE_LIGHTMODEL_SCENECOLOR:
  141. if (state[1] == 0) {
  142. /* front */
  143. GLint i;
  144. for (i = 0; i < 3; i++) {
  145. value[i] = ctx->Light.Model.Ambient[i]
  146. * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i]
  147. + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i];
  148. }
  149. value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
  150. }
  151. else {
  152. /* back */
  153. GLint i;
  154. for (i = 0; i < 3; i++) {
  155. value[i] = ctx->Light.Model.Ambient[i]
  156. * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i]
  157. + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i];
  158. }
  159. value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
  160. }
  161. return;
  162. case STATE_LIGHTPROD:
  163. {
  164. const GLuint ln = (GLuint) state[1];
  165. const GLuint face = (GLuint) state[2];
  166. GLint i;
  167. ASSERT(face == 0 || face == 1);
  168. switch (state[3]) {
  169. case STATE_AMBIENT:
  170. for (i = 0; i < 3; i++) {
  171. value[i] = ctx->Light.Light[ln].Ambient[i] *
  172. ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
  173. }
  174. /* [3] = material alpha */
  175. value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
  176. return;
  177. case STATE_DIFFUSE:
  178. for (i = 0; i < 3; i++) {
  179. value[i] = ctx->Light.Light[ln].Diffuse[i] *
  180. ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i];
  181. }
  182. /* [3] = material alpha */
  183. value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
  184. return;
  185. case STATE_SPECULAR:
  186. for (i = 0; i < 3; i++) {
  187. value[i] = ctx->Light.Light[ln].Specular[i] *
  188. ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
  189. }
  190. /* [3] = material alpha */
  191. value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
  192. return;
  193. default:
  194. _mesa_problem(ctx, "Invalid lightprod state in fetch_state");
  195. return;
  196. }
  197. }
  198. case STATE_TEXGEN:
  199. {
  200. /* state[1] is the texture unit */
  201. const GLuint unit = (GLuint) state[1];
  202. /* state[2] is the texgen attribute */
  203. switch (state[2]) {
  204. case STATE_TEXGEN_EYE_S:
  205. COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneS);
  206. return;
  207. case STATE_TEXGEN_EYE_T:
  208. COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneT);
  209. return;
  210. case STATE_TEXGEN_EYE_R:
  211. COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneR);
  212. return;
  213. case STATE_TEXGEN_EYE_Q:
  214. COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneQ);
  215. return;
  216. case STATE_TEXGEN_OBJECT_S:
  217. COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneS);
  218. return;
  219. case STATE_TEXGEN_OBJECT_T:
  220. COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneT);
  221. return;
  222. case STATE_TEXGEN_OBJECT_R:
  223. COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneR);
  224. return;
  225. case STATE_TEXGEN_OBJECT_Q:
  226. COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneQ);
  227. return;
  228. default:
  229. _mesa_problem(ctx, "Invalid texgen state in fetch_state");
  230. return;
  231. }
  232. }
  233. case STATE_TEXENV_COLOR:
  234. {
  235. /* state[1] is the texture unit */
  236. const GLuint unit = (GLuint) state[1];
  237. COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
  238. }
  239. return;
  240. case STATE_FOG_COLOR:
  241. COPY_4V(value, ctx->Fog.Color);
  242. return;
  243. case STATE_FOG_PARAMS:
  244. value[0] = ctx->Fog.Density;
  245. value[1] = ctx->Fog.Start;
  246. value[2] = ctx->Fog.End;
  247. value[3] = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
  248. return;
  249. case STATE_CLIPPLANE:
  250. {
  251. const GLuint plane = (GLuint) state[1];
  252. COPY_4V(value, ctx->Transform.EyeUserPlane[plane]);
  253. }
  254. return;
  255. case STATE_POINT_SIZE:
  256. value[0] = ctx->Point.Size;
  257. value[1] = ctx->Point.MinSize;
  258. value[2] = ctx->Point.MaxSize;
  259. value[3] = ctx->Point.Threshold;
  260. return;
  261. case STATE_POINT_ATTENUATION:
  262. value[0] = ctx->Point.Params[0];
  263. value[1] = ctx->Point.Params[1];
  264. value[2] = ctx->Point.Params[2];
  265. value[3] = 1.0F;
  266. return;
  267. case STATE_MATRIX:
  268. {
  269. /* state[1] = modelview, projection, texture, etc. */
  270. /* state[2] = which texture matrix or program matrix */
  271. /* state[3] = first row to fetch */
  272. /* state[4] = last row to fetch */
  273. /* state[5] = transpose, inverse or invtrans */
  274. const GLmatrix *matrix;
  275. const gl_state_index mat = state[1];
  276. const GLuint index = (GLuint) state[2];
  277. const GLuint firstRow = (GLuint) state[3];
  278. const GLuint lastRow = (GLuint) state[4];
  279. const gl_state_index modifier = state[5];
  280. const GLfloat *m;
  281. GLuint row, i;
  282. if (mat == STATE_MODELVIEW) {
  283. matrix = ctx->ModelviewMatrixStack.Top;
  284. }
  285. else if (mat == STATE_PROJECTION) {
  286. matrix = ctx->ProjectionMatrixStack.Top;
  287. }
  288. else if (mat == STATE_MVP) {
  289. matrix = &ctx->_ModelProjectMatrix;
  290. }
  291. else if (mat == STATE_TEXTURE) {
  292. matrix = ctx->TextureMatrixStack[index].Top;
  293. }
  294. else if (mat == STATE_PROGRAM) {
  295. matrix = ctx->ProgramMatrixStack[index].Top;
  296. }
  297. else {
  298. _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()");
  299. return;
  300. }
  301. if (modifier == STATE_MATRIX_INVERSE ||
  302. modifier == STATE_MATRIX_INVTRANS) {
  303. /* Be sure inverse is up to date:
  304. */
  305. _math_matrix_alloc_inv( (GLmatrix *) matrix );
  306. _math_matrix_analyse( (GLmatrix*) matrix );
  307. m = matrix->inv;
  308. }
  309. else {
  310. m = matrix->m;
  311. }
  312. if (modifier == STATE_MATRIX_TRANSPOSE ||
  313. modifier == STATE_MATRIX_INVTRANS) {
  314. for (i = 0, row = firstRow; row <= lastRow; row++) {
  315. value[i++] = m[row * 4 + 0];
  316. value[i++] = m[row * 4 + 1];
  317. value[i++] = m[row * 4 + 2];
  318. value[i++] = m[row * 4 + 3];
  319. }
  320. }
  321. else {
  322. for (i = 0, row = firstRow; row <= lastRow; row++) {
  323. value[i++] = m[row + 0];
  324. value[i++] = m[row + 4];
  325. value[i++] = m[row + 8];
  326. value[i++] = m[row + 12];
  327. }
  328. }
  329. }
  330. return;
  331. case STATE_DEPTH_RANGE:
  332. value[0] = ctx->Viewport.Near; /* near */
  333. value[1] = ctx->Viewport.Far; /* far */
  334. value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */
  335. value[3] = 0;
  336. return;
  337. case STATE_FRAGMENT_PROGRAM:
  338. {
  339. /* state[1] = {STATE_ENV, STATE_LOCAL} */
  340. /* state[2] = parameter index */
  341. const int idx = (int) state[2];
  342. switch (state[1]) {
  343. case STATE_ENV:
  344. COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
  345. break;
  346. case STATE_LOCAL:
  347. COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]);
  348. break;
  349. default:
  350. _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
  351. return;
  352. }
  353. }
  354. return;
  355. case STATE_VERTEX_PROGRAM:
  356. {
  357. /* state[1] = {STATE_ENV, STATE_LOCAL} */
  358. /* state[2] = parameter index */
  359. const int idx = (int) state[2];
  360. switch (state[1]) {
  361. case STATE_ENV:
  362. COPY_4V(value, ctx->VertexProgram.Parameters[idx]);
  363. break;
  364. case STATE_LOCAL:
  365. COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]);
  366. break;
  367. default:
  368. _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
  369. return;
  370. }
  371. }
  372. return;
  373. case STATE_INTERNAL:
  374. {
  375. switch (state[1]) {
  376. case STATE_NORMAL_SCALE:
  377. ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
  378. break;
  379. case STATE_TEXRECT_SCALE: {
  380. const int unit = (int) state[2];
  381. const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
  382. if (texObj) {
  383. struct gl_texture_image *texImage = texObj->Image[0][0];
  384. ASSIGN_4V(value, 1.0 / texImage->Width, 1.0 / texImage->Height, 0, 1);
  385. }
  386. break;
  387. }
  388. default:
  389. /* unknown state indexes are silently ignored
  390. * should be handled by the driver.
  391. */
  392. return;
  393. }
  394. }
  395. return;
  396. default:
  397. _mesa_problem(ctx, "Invalid state in _mesa_fetch_state");
  398. return;
  399. }
  400. }
  401. /**
  402. * Return a bitmask of the Mesa state flags (_NEW_* values) which would
  403. * indicate that the given context state may have changed.
  404. * The bitmask is used during validation to determine if we need to update
  405. * vertex/fragment program parameters (like "state.material.color") when
  406. * some GL state has changed.
  407. */
  408. GLbitfield
  409. _mesa_program_state_flags(const GLint state[])
  410. {
  411. switch (state[0]) {
  412. case STATE_MATERIAL:
  413. case STATE_LIGHT:
  414. case STATE_LIGHTMODEL_AMBIENT:
  415. case STATE_LIGHTMODEL_SCENECOLOR:
  416. case STATE_LIGHTPROD:
  417. return _NEW_LIGHT;
  418. case STATE_TEXGEN:
  419. case STATE_TEXENV_COLOR:
  420. return _NEW_TEXTURE;
  421. case STATE_FOG_COLOR:
  422. case STATE_FOG_PARAMS:
  423. return _NEW_FOG;
  424. case STATE_CLIPPLANE:
  425. return _NEW_TRANSFORM;
  426. case STATE_POINT_SIZE:
  427. case STATE_POINT_ATTENUATION:
  428. return _NEW_POINT;
  429. case STATE_MATRIX:
  430. switch (state[1]) {
  431. case STATE_MODELVIEW:
  432. return _NEW_MODELVIEW;
  433. case STATE_PROJECTION:
  434. return _NEW_PROJECTION;
  435. case STATE_MVP:
  436. return _NEW_MODELVIEW | _NEW_PROJECTION;
  437. case STATE_TEXTURE:
  438. return _NEW_TEXTURE_MATRIX;
  439. case STATE_PROGRAM:
  440. return _NEW_TRACK_MATRIX;
  441. default:
  442. _mesa_problem(NULL,
  443. "unexpected matrix in _mesa_program_state_flags()");
  444. return 0;
  445. }
  446. case STATE_DEPTH_RANGE:
  447. return _NEW_VIEWPORT;
  448. case STATE_FRAGMENT_PROGRAM:
  449. case STATE_VERTEX_PROGRAM:
  450. return _NEW_PROGRAM;
  451. case STATE_INTERNAL:
  452. switch (state[1]) {
  453. case STATE_NORMAL_SCALE:
  454. return _NEW_MODELVIEW;
  455. case STATE_TEXRECT_SCALE:
  456. return _NEW_TEXTURE;
  457. default:
  458. /* unknown state indexes are silently ignored and
  459. * no flag set, since it is handled by the driver.
  460. */
  461. return 0;
  462. }
  463. default:
  464. _mesa_problem(NULL, "unexpected state[0] in make_state_flags()");
  465. return 0;
  466. }
  467. }
  468. static void
  469. append(char *dst, const char *src)
  470. {
  471. while (*dst)
  472. dst++;
  473. while (*src)
  474. *dst++ = *src++;
  475. *dst = 0;
  476. }
  477. static void
  478. append_token(char *dst, gl_state_index k)
  479. {
  480. switch (k) {
  481. case STATE_MATERIAL:
  482. append(dst, "material.");
  483. break;
  484. case STATE_LIGHT:
  485. append(dst, "light");
  486. break;
  487. case STATE_LIGHTMODEL_AMBIENT:
  488. append(dst, "lightmodel.ambient");
  489. break;
  490. case STATE_LIGHTMODEL_SCENECOLOR:
  491. break;
  492. case STATE_LIGHTPROD:
  493. append(dst, "lightprod");
  494. break;
  495. case STATE_TEXGEN:
  496. append(dst, "texgen");
  497. break;
  498. case STATE_FOG_COLOR:
  499. append(dst, "fog.color");
  500. break;
  501. case STATE_FOG_PARAMS:
  502. append(dst, "fog.params");
  503. break;
  504. case STATE_CLIPPLANE:
  505. append(dst, "clip");
  506. break;
  507. case STATE_POINT_SIZE:
  508. append(dst, "point.size");
  509. break;
  510. case STATE_POINT_ATTENUATION:
  511. append(dst, "point.attenuation");
  512. break;
  513. case STATE_MATRIX:
  514. append(dst, "matrix.");
  515. break;
  516. case STATE_MODELVIEW:
  517. append(dst, "modelview");
  518. break;
  519. case STATE_PROJECTION:
  520. append(dst, "projection");
  521. break;
  522. case STATE_MVP:
  523. append(dst, "mvp");
  524. break;
  525. case STATE_TEXTURE:
  526. append(dst, "texture");
  527. break;
  528. case STATE_PROGRAM:
  529. append(dst, "program");
  530. break;
  531. case STATE_MATRIX_INVERSE:
  532. append(dst, ".inverse");
  533. break;
  534. case STATE_MATRIX_TRANSPOSE:
  535. append(dst, ".transpose");
  536. break;
  537. case STATE_MATRIX_INVTRANS:
  538. append(dst, ".invtrans");
  539. break;
  540. case STATE_AMBIENT:
  541. append(dst, "ambient");
  542. break;
  543. case STATE_DIFFUSE:
  544. append(dst, "diffuse");
  545. break;
  546. case STATE_SPECULAR:
  547. append(dst, "specular");
  548. break;
  549. case STATE_EMISSION:
  550. append(dst, "emission");
  551. break;
  552. case STATE_SHININESS:
  553. append(dst, "shininess");
  554. break;
  555. case STATE_HALF:
  556. append(dst, "half");
  557. break;
  558. case STATE_POSITION:
  559. append(dst, ".position");
  560. break;
  561. case STATE_ATTENUATION:
  562. append(dst, ".attenuation");
  563. break;
  564. case STATE_SPOT_DIRECTION:
  565. append(dst, ".spot.direction");
  566. break;
  567. case STATE_TEXGEN_EYE_S:
  568. append(dst, "eye.s");
  569. break;
  570. case STATE_TEXGEN_EYE_T:
  571. append(dst, "eye.t");
  572. break;
  573. case STATE_TEXGEN_EYE_R:
  574. append(dst, "eye.r");
  575. break;
  576. case STATE_TEXGEN_EYE_Q:
  577. append(dst, "eye.q");
  578. break;
  579. case STATE_TEXGEN_OBJECT_S:
  580. append(dst, "object.s");
  581. break;
  582. case STATE_TEXGEN_OBJECT_T:
  583. append(dst, "object.t");
  584. break;
  585. case STATE_TEXGEN_OBJECT_R:
  586. append(dst, "object.r");
  587. break;
  588. case STATE_TEXGEN_OBJECT_Q:
  589. append(dst, "object.q");
  590. break;
  591. case STATE_TEXENV_COLOR:
  592. append(dst, "texenv");
  593. break;
  594. case STATE_DEPTH_RANGE:
  595. append(dst, "depth.range");
  596. break;
  597. case STATE_VERTEX_PROGRAM:
  598. case STATE_FRAGMENT_PROGRAM:
  599. break;
  600. case STATE_ENV:
  601. append(dst, "env");
  602. break;
  603. case STATE_LOCAL:
  604. append(dst, "local");
  605. break;
  606. case STATE_INTERNAL:
  607. case STATE_NORMAL_SCALE:
  608. case STATE_POSITION_NORMALIZED:
  609. append(dst, "(internal)");
  610. break;
  611. default:
  612. ;
  613. }
  614. }
  615. static void
  616. append_face(char *dst, GLint face)
  617. {
  618. if (face == 0)
  619. append(dst, "front.");
  620. else
  621. append(dst, "back.");
  622. }
  623. static void
  624. append_index(char *dst, GLint index)
  625. {
  626. char s[20];
  627. _mesa_sprintf(s, "[%d].", index);
  628. append(dst, s);
  629. }
  630. /**
  631. * Make a string from the given state vector.
  632. * For example, return "state.matrix.texture[2].inverse".
  633. * Use _mesa_free() to deallocate the string.
  634. */
  635. const char *
  636. _mesa_program_state_string(const GLint state[6])
  637. {
  638. char str[1000] = "";
  639. char tmp[30];
  640. append(str, "state.");
  641. append_token(str, (gl_state_index) state[0]);
  642. switch (state[0]) {
  643. case STATE_MATERIAL:
  644. append_face(str, state[1]);
  645. append_token(str, (gl_state_index) state[2]);
  646. break;
  647. case STATE_LIGHT:
  648. append(str, "light");
  649. append_index(str, state[1]); /* light number [i]. */
  650. append_token(str, (gl_state_index) state[2]); /* coefficients */
  651. break;
  652. case STATE_LIGHTMODEL_AMBIENT:
  653. append(str, "lightmodel.ambient");
  654. break;
  655. case STATE_LIGHTMODEL_SCENECOLOR:
  656. if (state[1] == 0) {
  657. append(str, "lightmodel.front.scenecolor");
  658. }
  659. else {
  660. append(str, "lightmodel.back.scenecolor");
  661. }
  662. break;
  663. case STATE_LIGHTPROD:
  664. append_index(str, state[1]); /* light number [i]. */
  665. append_face(str, state[2]);
  666. append_token(str, (gl_state_index) state[3]);
  667. break;
  668. case STATE_TEXGEN:
  669. append_index(str, state[1]); /* tex unit [i] */
  670. append_token(str, (gl_state_index) state[2]); /* plane coef */
  671. break;
  672. case STATE_TEXENV_COLOR:
  673. append_index(str, state[1]); /* tex unit [i] */
  674. append(str, "color");
  675. break;
  676. case STATE_FOG_COLOR:
  677. case STATE_FOG_PARAMS:
  678. break;
  679. case STATE_CLIPPLANE:
  680. append_index(str, state[1]); /* plane [i] */
  681. append(str, "plane");
  682. break;
  683. case STATE_POINT_SIZE:
  684. case STATE_POINT_ATTENUATION:
  685. break;
  686. case STATE_MATRIX:
  687. {
  688. /* state[1] = modelview, projection, texture, etc. */
  689. /* state[2] = which texture matrix or program matrix */
  690. /* state[3] = first row to fetch */
  691. /* state[4] = last row to fetch */
  692. /* state[5] = transpose, inverse or invtrans */
  693. const gl_state_index mat = (gl_state_index) state[1];
  694. const GLuint index = (GLuint) state[2];
  695. const GLuint firstRow = (GLuint) state[3];
  696. const GLuint lastRow = (GLuint) state[4];
  697. const gl_state_index modifier = (gl_state_index) state[5];
  698. append_token(str, mat);
  699. if (index)
  700. append_index(str, index);
  701. if (modifier)
  702. append_token(str, modifier);
  703. if (firstRow == lastRow)
  704. _mesa_sprintf(tmp, ".row[%d]", firstRow);
  705. else
  706. _mesa_sprintf(tmp, ".row[%d..%d]", firstRow, lastRow);
  707. append(str, tmp);
  708. }
  709. break;
  710. case STATE_DEPTH_RANGE:
  711. break;
  712. case STATE_FRAGMENT_PROGRAM:
  713. case STATE_VERTEX_PROGRAM:
  714. /* state[1] = {STATE_ENV, STATE_LOCAL} */
  715. /* state[2] = parameter index */
  716. append_token(str, (gl_state_index) state[1]);
  717. append_index(str, state[2]);
  718. break;
  719. case STATE_INTERNAL:
  720. break;
  721. default:
  722. _mesa_problem(NULL, "Invalid state in _mesa_program_state_string");
  723. break;
  724. }
  725. return _mesa_strdup(str);
  726. }
  727. /**
  728. * Loop over all the parameters in a parameter list. If the parameter
  729. * is a GL state reference, look up the current value of that state
  730. * variable and put it into the parameter's Value[4] array.
  731. * This would be called at glBegin time when using a fragment program.
  732. */
  733. void
  734. _mesa_load_state_parameters(GLcontext *ctx,
  735. struct gl_program_parameter_list *paramList)
  736. {
  737. GLuint i;
  738. if (!paramList)
  739. return;
  740. for (i = 0; i < paramList->NumParameters; i++) {
  741. if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
  742. _mesa_fetch_state(ctx,
  743. paramList->Parameters[i].StateIndexes,
  744. paramList->ParameterValues[i]);
  745. }
  746. }
  747. }