gsd_wire.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. /*!
  2. \file lib/ogsf/gsd_wire.c
  3. \brief OGSF library -
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Bill Brown USACERL (January 1993)
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <grass/gis.h>
  14. #include <grass/ogsf.h>
  15. #include "gsget.h"
  16. #include "rowcol.h"
  17. #define DO_ARROWS
  18. /************************************************************************/
  19. /* Notes on exageration:
  20. vertical exageration is of two forms:
  21. 1) global exageration (from geoview struct)
  22. 2) vertical exageration for each surface - not implemented
  23. */
  24. /************************************************************************/
  25. /* may need to add more parameters to tell it which window or off_screen
  26. * pixmap to draw into. nah - just have one current (OpenGL limitation)
  27. */
  28. /*!
  29. \brief Draw surface wire
  30. \param surf surface (geosurf)
  31. \return
  32. */
  33. int gsd_wire_surf(geosurf * surf)
  34. {
  35. int desc, ret;
  36. G_debug(3, "gsd_wire_surf(): id=%d", surf->gsurf_id);
  37. desc = ATT_TOPO;
  38. switch (gs_get_att_src(surf, desc)) {
  39. case NOTSET_ATT:
  40. ret = (-1);
  41. break;
  42. case MAP_ATT:
  43. if (surf->draw_mode & DM_GRID_WIRE)
  44. ret = (gsd_wire_surf_map(surf)); /* draw mesh */
  45. else
  46. ret = (gsd_coarse_surf_map(surf)); /* draw coarse surf */
  47. #ifdef DO_ARROWS
  48. /*
  49. gsd_wire_arrows(surf);
  50. */
  51. #endif
  52. break;
  53. case CONST_ATT:
  54. ret = (gsd_wire_surf_const(surf, surf->att[desc].constant));
  55. break;
  56. case FUNC_ATT:
  57. ret = (gsd_wire_surf_func(surf, surf->att[desc].user_func));
  58. break;
  59. default:
  60. ret = (-1);
  61. break;
  62. }
  63. return (ret);
  64. }
  65. /*!
  66. \brief ADD
  67. \param surf surface (geosurf)
  68. \return
  69. */
  70. int gsd_wire_surf_map(geosurf * surf)
  71. {
  72. int check_mask, check_color;
  73. typbuff *buff, *cobuff;
  74. int xmod, ymod, row, col, cnt, xcnt, ycnt, x1off;
  75. long offset, y1off;
  76. float pt[4], xres, yres, ymax, zexag;
  77. int col_src, curcolor;
  78. gsurf_att *coloratt;
  79. G_debug(3, "gsd_wire_surf_map");
  80. buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
  81. cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
  82. gs_update_curmask(surf);
  83. check_mask = surf->curmask ? 1 : 0;
  84. /*
  85. checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
  86. combine it/them with any current mask, put in typbuff:
  87. if(surf->att[ATT_TOPO].constant)
  88. */
  89. xmod = surf->x_modw;
  90. ymod = surf->y_modw;
  91. xres = xmod * surf->xres;
  92. yres = ymod * surf->yres;
  93. ymax = (surf->rows - 1) * surf->yres;
  94. xcnt = 1 + (surf->cols - 1) / xmod;
  95. ycnt = 1 + (surf->rows - 1) / ymod;
  96. gsd_pushmatrix();
  97. gsd_do_scale(1);
  98. gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
  99. zexag = surf->z_exag;
  100. gsd_colormode(CM_COLOR);
  101. /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
  102. or else use more general and inefficient gets */
  103. check_color = (surf->wire_color == WC_COLOR_ATT);
  104. if (check_color) {
  105. coloratt = &(surf->att[ATT_COLOR]);
  106. col_src = surf->att[ATT_COLOR].att_src;
  107. if (col_src != MAP_ATT) {
  108. if (col_src == CONST_ATT) {
  109. gsd_color_func((int)surf->att[ATT_COLOR].constant);
  110. }
  111. else {
  112. gsd_color_func(surf->wire_color);
  113. }
  114. check_color = 0;
  115. }
  116. }
  117. else {
  118. gsd_color_func(surf->wire_color);
  119. }
  120. /* would also be good to check if colormap == surfmap, to increase speed */
  121. for (row = 0; row < ycnt; row++) {
  122. pt[Y] = ymax - row * yres;
  123. y1off = row * ymod * surf->cols;
  124. gsd_bgnline();
  125. cnt = 0;
  126. for (col = 0; col < xcnt; col++) {
  127. pt[X] = col * xres;
  128. x1off = col * xmod;
  129. offset = x1off + y1off;
  130. if (check_mask) {
  131. if (BM_get(surf->curmask, col * xmod, row * ymod)) {
  132. gsd_endline();
  133. gsd_bgnline();
  134. cnt = 0;
  135. continue;
  136. }
  137. }
  138. GET_MAPATT(buff, offset, pt[Z]);
  139. if (check_color) {
  140. curcolor = gs_mapcolor(cobuff, coloratt, offset);
  141. gsd_color_func(curcolor);
  142. /* could use this & skip the GET if colordata == elevdata
  143. gsd_color_func(gs_fastmapcolor(cobuff, coloratt, offset,
  144. (int)pt[Z]));
  145. */
  146. }
  147. pt[Z] = pt[Z] * zexag;
  148. gsd_vert_func(pt);
  149. if (cnt == 255) {
  150. gsd_endline();
  151. gsd_bgnline();
  152. cnt = 0;
  153. gsd_vert_func(pt);
  154. }
  155. cnt++;
  156. }
  157. gsd_endline();
  158. }
  159. for (col = 0; col < xcnt; col++) {
  160. pt[X] = col * xres;
  161. x1off = col * xmod;
  162. gsd_bgnline();
  163. cnt = 0;
  164. for (row = 0; row < ycnt; row++) {
  165. pt[Y] = ymax - row * yres;
  166. y1off = row * ymod * surf->cols;
  167. offset = x1off + y1off;
  168. if (check_mask) {
  169. if (BM_get(surf->curmask, col * xmod, row * ymod)) {
  170. gsd_endline();
  171. gsd_bgnline();
  172. cnt = 0;
  173. continue;
  174. }
  175. }
  176. GET_MAPATT(buff, offset, pt[Z]);
  177. if (check_color) {
  178. curcolor = gs_mapcolor(cobuff, coloratt, offset);
  179. gsd_color_func(curcolor);
  180. /* could use this & skip the GET if colordata == elevdata
  181. gsd_color_func(gs_fastmapcolor(coloratt, offset, (int)pt[Z]));
  182. */
  183. }
  184. pt[Z] = pt[Z] * zexag;
  185. gsd_vert_func(pt);
  186. if (cnt == 255) {
  187. gsd_endline();
  188. gsd_bgnline();
  189. cnt = 0;
  190. gsd_vert_func(pt);
  191. }
  192. cnt++;
  193. }
  194. gsd_endline();
  195. }
  196. gsd_popmatrix();
  197. gsd_colormode(CM_DIFFUSE);
  198. return (1);
  199. }
  200. /*!
  201. \brief ADD
  202. \param surf surface (geosurf)
  203. \param k
  204. \return
  205. */
  206. int gsd_wire_surf_const(geosurf * surf, float k)
  207. {
  208. int do_diff, check_mask, check_color;
  209. int xmod, ymod, row, col, cnt, xcnt, ycnt, x1off;
  210. long offset, y1off;
  211. float pt[4], xres, yres, ymax, zexag;
  212. int col_src;
  213. gsurf_att *coloratt;
  214. typbuff *cobuff;
  215. G_debug(3, "gsd_wire_surf_const");
  216. cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
  217. gs_update_curmask(surf);
  218. check_mask = surf->curmask ? 1 : 0;
  219. do_diff = (NULL != gsdiff_get_SDref());
  220. xmod = surf->x_modw;
  221. ymod = surf->y_modw;
  222. xres = xmod * surf->xres;
  223. yres = ymod * surf->yres;
  224. xcnt = 1 + (surf->cols - 1) / xmod;
  225. ycnt = 1 + (surf->rows - 1) / ymod;
  226. ymax = (surf->rows - 1) * surf->yres;
  227. gsd_pushmatrix();
  228. gsd_do_scale(1);
  229. gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
  230. zexag = surf->z_exag;
  231. gsd_colormode(CM_COLOR);
  232. /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
  233. or else use more general and inefficient gets */
  234. check_color = (surf->wire_color == WC_COLOR_ATT);
  235. if (check_color) {
  236. coloratt = &(surf->att[ATT_COLOR]);
  237. col_src = surf->att[ATT_COLOR].att_src;
  238. if (col_src != MAP_ATT) {
  239. if (col_src == CONST_ATT) {
  240. gsd_color_func((int)surf->att[ATT_COLOR].constant);
  241. }
  242. else {
  243. gsd_color_func(surf->wire_color);
  244. }
  245. check_color = 0;
  246. }
  247. }
  248. else {
  249. gsd_color_func(surf->wire_color);
  250. }
  251. pt[Z] = k * zexag;
  252. for (row = 0; row < ycnt; row++) {
  253. pt[Y] = ymax - row * yres;
  254. y1off = row * ymod * surf->cols;
  255. gsd_bgnline();
  256. cnt = 0;
  257. for (col = 0; col < xcnt; col++) {
  258. pt[X] = col * xres;
  259. x1off = col * xmod;
  260. offset = x1off + y1off;
  261. if (check_mask) {
  262. if (BM_get(surf->curmask, col * xmod, row * ymod)) {
  263. gsd_endline();
  264. gsd_bgnline();
  265. cnt = 0;
  266. continue;
  267. }
  268. }
  269. if (check_color) {
  270. gsd_color_func(gs_mapcolor(cobuff, coloratt, offset));
  271. }
  272. if (do_diff) {
  273. pt[Z] = gsdiff_do_SD(k * zexag, offset);
  274. }
  275. gsd_vert_func(pt);
  276. if (cnt == 255) {
  277. gsd_endline();
  278. gsd_bgnline();
  279. cnt = 0;
  280. gsd_vert_func(pt);
  281. }
  282. cnt++;
  283. }
  284. gsd_endline();
  285. }
  286. for (col = 0; col < xcnt; col++) {
  287. pt[X] = col * xres;
  288. x1off = col * xmod;
  289. gsd_bgnline();
  290. cnt = 0;
  291. for (row = 0; row < ycnt; row++) {
  292. pt[Y] = ymax - row * yres;
  293. y1off = row * ymod * surf->cols;
  294. offset = x1off + y1off;
  295. if (check_mask) {
  296. if (BM_get(surf->curmask, col * xmod, row * ymod)) {
  297. gsd_endline();
  298. gsd_bgnline();
  299. cnt = 0;
  300. continue;
  301. }
  302. }
  303. if (check_color) {
  304. gsd_color_func(gs_mapcolor(cobuff, coloratt, offset));
  305. }
  306. if (do_diff) {
  307. pt[Z] = gsdiff_do_SD(k * zexag, offset);
  308. }
  309. gsd_vert_func(pt);
  310. if (cnt == 255) {
  311. gsd_endline();
  312. gsd_bgnline();
  313. cnt = 0;
  314. gsd_vert_func(pt);
  315. }
  316. cnt++;
  317. }
  318. gsd_endline();
  319. }
  320. gsd_popmatrix();
  321. gsd_colormode(CM_DIFFUSE);
  322. return (1);
  323. }
  324. /*!
  325. \brief ADD
  326. Not yet implemented.
  327. \param gs surface (geosurf)
  328. \param user_func user defined function
  329. \return 1
  330. */
  331. int gsd_wire_surf_func(geosurf * gs, int (*user_func) ())
  332. {
  333. return (1);
  334. }
  335. /*!
  336. \brief ADD
  337. Need to do Zexag scale of normal for arrow direction, drawing
  338. routine unexags z for arrow
  339. \param surf surface (geosurf)
  340. \return
  341. */
  342. int gsd_wire_arrows(geosurf * surf)
  343. {
  344. typbuff *buff, *cobuff;
  345. int check_mask, check_color;
  346. int xmod, ymod, row, col, xcnt, ycnt;
  347. long offset, y1off;
  348. float tx, ty, tz, sz;
  349. float n[3], pt[4], xres, yres, ymax, zexag;
  350. int col_src, curcolor;
  351. gsurf_att *coloratt;
  352. G_debug(3, "gsd_norm_arrows");
  353. /* avoid scaling by zero */
  354. GS_get_scale(&tx, &ty, &tz, 1);
  355. if (tz == 0.0) {
  356. return (0);
  357. }
  358. sz = GS_global_exag();
  359. gs_update_curmask(surf);
  360. check_mask = surf->curmask ? 1 : 0;
  361. /*
  362. checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
  363. combine it/them with any current mask, put in surf->curmask:
  364. */
  365. check_color = 1;
  366. curcolor = 0;
  367. coloratt = &(surf->att[ATT_COLOR]);
  368. col_src = surf->att[ATT_COLOR].att_src;
  369. if (col_src != MAP_ATT) {
  370. if (col_src == CONST_ATT) {
  371. curcolor = (int)surf->att[ATT_COLOR].constant;
  372. }
  373. else {
  374. curcolor = surf->wire_color;
  375. }
  376. check_color = 0;
  377. }
  378. buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
  379. cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
  380. xmod = surf->x_modw;
  381. ymod = surf->y_modw;
  382. xres = xmod * surf->xres;
  383. yres = ymod * surf->yres;
  384. ymax = (surf->rows - 1) * surf->yres;
  385. xcnt = 1 + (surf->cols - 1) / xmod;
  386. ycnt = 1 + (surf->rows - 1) / ymod;
  387. gsd_pushmatrix();
  388. gsd_do_scale(1);
  389. gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
  390. zexag = surf->z_exag;
  391. /* CURRENTLY ALWAYS 1.0 */
  392. gsd_colormode(CM_COLOR);
  393. for (row = 0; row < ycnt; row++) {
  394. pt[Y] = ymax - row * yres;
  395. y1off = row * ymod * surf->cols;
  396. for (col = 0; col < xcnt; col++) {
  397. pt[X] = col * xres;
  398. offset = col * xmod + y1off;
  399. if (check_mask) {
  400. if (BM_get(surf->curmask, col * xmod, row * ymod)) {
  401. continue;
  402. }
  403. }
  404. FNORM(surf->norms[offset], n);
  405. GET_MAPATT(buff, offset, pt[Z]);
  406. pt[Z] *= zexag;
  407. if (check_color) {
  408. curcolor = gs_mapcolor(cobuff, coloratt, offset);
  409. }
  410. gsd_arrow(pt, curcolor, xres * 2, n, sz, surf);
  411. } /* ea col */
  412. } /* ea row */
  413. gsd_popmatrix();
  414. gsd_colormode(CM_DIFFUSE);
  415. return (1);
  416. }
  417. /*!
  418. \brief Draw coarse surface
  419. New (TEST) wire routine that draws low res surface
  420. Based on new Trinagle Fan routine
  421. Resolution is a function of current surface resolution
  422. times wire resolution
  423. \todo normals have to be recalculated before proper low
  424. res surface can be drawn
  425. In window optimization has been removed
  426. \param surf surface (geosurf)
  427. \return
  428. */
  429. int gsd_coarse_surf_map(geosurf * surf)
  430. {
  431. int check_mask, check_color, check_transp;
  432. int check_material, check_emis, check_shin;
  433. typbuff *buff, *cobuff, *trbuff, *embuff, *shbuff;
  434. int xmod, ymod;
  435. int row, col, xcnt, ycnt;
  436. long y1off, y2off, y3off;
  437. long offset2[10];
  438. float pt2[10][2];
  439. int ii;
  440. float x1, x2, x3, y1, y2, y3, tx, ty, tz, ttr;
  441. float n[3], pt[4], xres, yres, ymax, zexag;
  442. int em_src, sh_src, trans_src, col_src, curcolor;
  443. gsurf_att *ematt, *shatt, *tratt, *coloratt;
  444. int datarow1, datacol1, datarow2, datacol2, datarow3, datacol3;
  445. float kem, ksh, pkem, pksh;
  446. unsigned int ktrans;
  447. int step_val = 2 * surf->x_modw; /* should always be factor of 2 for fan */
  448. int start_val = surf->x_modw;
  449. /* ensure normals are correct */
  450. gs_calc_normals(surf);
  451. /* avoid scaling by zero */
  452. GS_get_scale(&tx, &ty, &tz, 1);
  453. if (tz == 0.0) {
  454. return (gsd_surf_const(surf, 0.0));
  455. }
  456. /* else if (surf->z_exag == 0.0)
  457. {
  458. return(gsd_surf_const(surf, surf->z_min));
  459. }
  460. NOT YET IMPLEMENTED */
  461. buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
  462. cobuff = gs_get_att_typbuff(surf, ATT_COLOR, 0);
  463. gs_update_curmask(surf);
  464. check_mask = surf->curmask ? 1 : 0;
  465. /*
  466. checks ATT_TOPO & ATT_COLOR no_zero flags, make a mask from each,
  467. combine it/them with any current mask, put in surf->curmask:
  468. */
  469. xmod = surf->x_mod;
  470. ymod = surf->y_mod;
  471. xres = xmod * surf->xres;
  472. yres = ymod * surf->yres;
  473. ymax = (surf->rows - 1) * surf->yres;
  474. xcnt = VCOLS(surf);
  475. ycnt = VROWS(surf);
  476. gsd_pushmatrix();
  477. gsd_do_scale(1);
  478. gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
  479. zexag = surf->z_exag;
  480. gsd_colormode(CM_DIFFUSE);
  481. /* CURRENTLY ALWAYS 1.0 */
  482. #ifdef CALC_AREA
  483. sz = GS_global_exag();
  484. #endif
  485. /* TODO: get rid of (define) these magic numbers scaling the attribute vals */
  486. check_transp = 0;
  487. tratt = &(surf->att[ATT_TRANSP]);
  488. ktrans = (255 << 24);
  489. trans_src = surf->att[ATT_TRANSP].att_src;
  490. if (CONST_ATT == trans_src && surf->att[ATT_TRANSP].constant != 0.0) {
  491. ktrans = (255 - (int)surf->att[ATT_TRANSP].constant) << 24;
  492. gsd_blend(1);
  493. gsd_zwritemask(0x0);
  494. }
  495. else if (MAP_ATT == trans_src) {
  496. trbuff = gs_get_att_typbuff(surf, ATT_TRANSP, 0);
  497. check_transp = trbuff ? 1 : 0;
  498. gsd_blend(1);
  499. gsd_zwritemask(0x0);
  500. }
  501. check_emis = 0;
  502. ematt = &(surf->att[ATT_EMIT]);
  503. kem = 0.0;
  504. pkem = 1.0;
  505. em_src = surf->att[ATT_EMIT].att_src;
  506. if (CONST_ATT == em_src) {
  507. kem = surf->att[ATT_EMIT].constant / 255.;
  508. }
  509. else if (MAP_ATT == em_src) {
  510. embuff = gs_get_att_typbuff(surf, ATT_EMIT, 0);
  511. check_emis = embuff ? 1 : 0;
  512. }
  513. check_shin = 0;
  514. shatt = &(surf->att[ATT_SHINE]);
  515. ksh = 0.0;
  516. pksh = 1.0;
  517. sh_src = surf->att[ATT_SHINE].att_src;
  518. if (CONST_ATT == sh_src) {
  519. ksh = surf->att[ATT_SHINE].constant / 255.;
  520. gsd_set_material(1, 0, ksh, kem, 0x0);
  521. }
  522. else if (MAP_ATT == sh_src) {
  523. shbuff = gs_get_att_typbuff(surf, ATT_SHINE, 0);
  524. check_shin = shbuff ? 1 : 0;
  525. }
  526. /* will need to check for color source of FUNC_ATT & NOTSET_ATT,
  527. or else use more general and inefficient gets */
  528. check_color = 1;
  529. curcolor = 0;
  530. coloratt = &(surf->att[ATT_COLOR]);
  531. col_src = surf->att[ATT_COLOR].att_src;
  532. if (col_src != MAP_ATT) {
  533. if (col_src == CONST_ATT) {
  534. curcolor = (int)surf->att[ATT_COLOR].constant;
  535. }
  536. else {
  537. curcolor = surf->wire_color;
  538. }
  539. check_color = 0;
  540. }
  541. check_material = (check_shin || check_emis || (kem && check_color));
  542. /* would also be good to check if colormap == surfmap, to increase speed */
  543. /* will also need to set check_transp, check_shine, etc & fix material */
  544. for (row = start_val; row <= ycnt - start_val; row += step_val) {
  545. datarow1 = row * ymod;
  546. datarow2 = (row - (step_val / 2)) * ymod;
  547. datarow3 = (row + (step_val / 2)) * ymod;
  548. y1 = ymax - row * yres;
  549. y2 = ymax - (row - (step_val / 2)) * yres;
  550. y3 = ymax - (row + (step_val / 2)) * yres;
  551. y1off = row * ymod * surf->cols;
  552. y2off = (row - (step_val / 2)) * ymod * surf->cols;
  553. y3off = (row + (step_val / 2)) * ymod * surf->cols;
  554. for (col = start_val; col <= xcnt - start_val; col += step_val) {
  555. datacol1 = col * xmod;
  556. datacol2 = (col - (step_val / 2)) * xmod;
  557. datacol3 = (col + (step_val / 2)) * xmod;
  558. x1 = col * xres;
  559. x2 = (col - (step_val / 2)) * xres;
  560. x3 = (col + (step_val / 2)) * xres;
  561. /* Do not need BM_get because GET_MAPATT calls
  562. * same and returns zero if masked
  563. */
  564. offset2[0] = y1off + datacol1; /* fan center */
  565. pt2[0][X] = x1;
  566. pt2[0][Y] = y1; /* fan center */
  567. pt[X] = pt2[0][X];
  568. pt[Y] = pt2[0][Y];
  569. if (!GET_MAPATT(buff, offset2[0], pt[Z]))
  570. continue; /* masked */
  571. pt[Z] *= zexag;
  572. offset2[1] = y2off + datacol2;
  573. offset2[2] = y2off + datacol1;
  574. offset2[3] = y2off + datacol3;
  575. offset2[4] = y1off + datacol3;
  576. offset2[5] = y3off + datacol3;
  577. offset2[6] = y3off + datacol1;
  578. offset2[7] = y3off + datacol2;
  579. offset2[8] = y1off + datacol2;
  580. offset2[9] = y2off + datacol2; /* repeat 1st corner to close */
  581. pt2[1][X] = x2;
  582. pt2[1][Y] = y2;
  583. pt2[2][X] = x1;
  584. pt2[2][Y] = y2;
  585. pt2[3][X] = x3;
  586. pt2[3][Y] = y2;
  587. pt2[4][X] = x3;
  588. pt2[4][Y] = y1;
  589. pt2[5][X] = x3;
  590. pt2[5][Y] = y3;
  591. pt2[6][X] = x1;
  592. pt2[6][Y] = y3;
  593. pt2[7][X] = x2;
  594. pt2[7][Y] = y3;
  595. pt2[8][X] = x2;
  596. pt2[8][Y] = y1;
  597. pt2[9][X] = x2;
  598. pt2[9][Y] = y2; /* repeat 1st corner to close */
  599. /* Run through triangle fan */
  600. gsd_bgntfan();
  601. for (ii = 0; ii < 10; ii++) {
  602. if (ii > 0) {
  603. pt[X] = pt2[ii][X];
  604. pt[Y] = pt2[ii][Y];
  605. if (!GET_MAPATT(buff, offset2[ii], pt[Z]))
  606. continue;
  607. pt[Z] *= zexag;
  608. }
  609. FNORM(surf->norms[offset2[ii]], n);
  610. if (check_color)
  611. curcolor = gs_mapcolor(cobuff, coloratt, offset2[ii]);
  612. if (check_transp) {
  613. GET_MAPATT(trbuff, offset2[ii], ttr);
  614. ktrans = (char)SCALE_ATT(tratt, ttr, 0, 255);
  615. ktrans = (char)(255 - ktrans) << 24;
  616. }
  617. if (check_material) {
  618. if (check_emis) {
  619. GET_MAPATT(embuff, offset2[ii], kem);
  620. kem = SCALE_ATT(ematt, kem, 0., 1.);
  621. }
  622. if (check_shin) {
  623. GET_MAPATT(shbuff, offset2[ii], ksh);
  624. ksh = SCALE_ATT(shatt, ksh, 0., 1.);
  625. }
  626. if (pksh != ksh || pkem != kem || (kem && check_color)) {
  627. pksh = ksh;
  628. pkem = kem;
  629. gsd_set_material(check_shin, check_emis,
  630. ksh, kem, curcolor);
  631. }
  632. }
  633. gsd_litvert_func(n, ktrans | curcolor, pt);
  634. } /* close ii loop */
  635. gsd_endtfan();
  636. } /* end col */
  637. } /* end row */
  638. gsd_popmatrix();
  639. /*
  640. gsd_colormode(CM_DIFFUSE);
  641. */
  642. gsd_blend(0);
  643. gsd_zwritemask(0xffffffff);
  644. return (0);
  645. }