gsd_fringe.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. /*!
  2. \file lib/ogsf/gsd_fonts.c
  3. \brief OGSF library - manipulating surfaces/fridge (lower level function)
  4. GRASS OpenGL gsurf OGSF Library
  5. \todo This file needs to be re-written in OpenGL
  6. (C) 1999-2008 by the GRASS Development Team
  7. This program is free software under the
  8. GNU General Public License (>=v2).
  9. Read the file COPYING that comes with GRASS
  10. for details.
  11. \author Bill Brown USACERL, GMSL/University of Illinois
  12. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  13. */
  14. #include <grass/ogsf.h>
  15. #include "gsget.h"
  16. #include "rowcol.h"
  17. #define FRINGE_FORE 0x000000
  18. #define FRINGE_WIDTH 2
  19. /*!
  20. \brief Normals
  21. */
  22. float Nnorth[] = { 0.0, 0.8, 0.6 };
  23. float Nsouth[] = { 0.0, -0.8, 0.6 };
  24. float Neast[] = { 0.8, 0.0, 0.6 };
  25. float Nwest[] = { -0.8, 0.0, 0.6 };
  26. float Ntop[] = { 0.0, 0.0, 1.0 };
  27. float Nbottom[] = { 0.0, 0.0, -1.0 };
  28. /*!
  29. \brief Display fridge
  30. \todo add elevation for bottom
  31. add color option
  32. add ruler grid lines
  33. \param surf surface (geosurf)
  34. \param clr
  35. \param elev
  36. \param where
  37. */
  38. void gsd_display_fringe(geosurf * surf, unsigned long clr, float elev,
  39. int where[4])
  40. {
  41. float bot, xres, yres; /* world size of view cell */
  42. int ycnt, xcnt; /* number of view cells across */
  43. float xmax, ymax;
  44. xres = surf->x_mod * surf->xres;
  45. yres = surf->y_mod * surf->yres;
  46. xcnt = VCOLS(surf);
  47. ycnt = VROWS(surf);
  48. xmax = surf->xmax;
  49. ymax = surf->ymax;
  50. /*
  51. bot = surf->zmin - ((surf->zrange/4.) * surf->z_exag);
  52. */
  53. bot = elev - ((surf->zrange / 4.) * surf->z_exag);
  54. gsd_linewidth(FRINGE_WIDTH);
  55. gsd_colormode(CM_COLOR);
  56. /* North fringe */
  57. if (where[0] || where[1]) {
  58. glNormal3fv(Nnorth);
  59. gsd_color_func(clr);
  60. gsd_zwritemask(0x0);
  61. gsd_fringe_horiz_poly(bot, surf, 0, 0);
  62. gsd_color_func(FRINGE_FORE); /* WHITE */
  63. gsd_fringe_horiz_line(bot, surf, 0, 0);
  64. gsd_zwritemask(0xffffffff);
  65. /* wmpack (0); ??? glColorMask */
  66. gsd_color_func(clr);
  67. gsd_fringe_horiz_poly(bot, surf, 0, 0);
  68. }
  69. /* South fringe */
  70. if (where[2] || where[3]) {
  71. glNormal3fv(Nsouth);
  72. gsd_color_func(clr);
  73. gsd_zwritemask(0x0);
  74. gsd_fringe_horiz_poly(bot, surf, ycnt - 2, 1);
  75. gsd_color_func(FRINGE_FORE); /* WHITE */
  76. gsd_fringe_horiz_line(bot, surf, ycnt - 2, 1);
  77. gsd_zwritemask(0xffffffff);
  78. /* wmpack (0); ??? glColorMask */
  79. gsd_color_func(clr);
  80. gsd_fringe_horiz_poly(bot, surf, ycnt - 2, 1);
  81. }
  82. /* West fringe */
  83. if (where[0] || where[2]) {
  84. glNormal3fv(Nwest);
  85. gsd_color_func(clr);
  86. gsd_zwritemask(0x0);
  87. gsd_fringe_vert_poly(bot, surf, 0, 0);
  88. gsd_color_func(FRINGE_FORE);
  89. gsd_fringe_vert_line(bot, surf, 0, 0);
  90. gsd_zwritemask(0xffffffff);
  91. gsd_color_func(clr);
  92. gsd_fringe_vert_poly(bot, surf, 0, 0);
  93. }
  94. /* East fringe */
  95. if (where[1] || where[3]) {
  96. glNormal3fv(Neast);
  97. gsd_color_func(clr);
  98. gsd_zwritemask(0x0);
  99. gsd_fringe_vert_poly(bot, surf, xcnt - 2, 1);
  100. gsd_color_func(FRINGE_FORE);
  101. gsd_fringe_vert_line(bot, surf, xcnt - 2, 1);
  102. gsd_zwritemask(0xffffffff);
  103. gsd_color_func(clr);
  104. gsd_fringe_vert_poly(bot, surf, xcnt - 2, 1);
  105. }
  106. return;
  107. }
  108. /*!
  109. \brief Draw fringe polygon in x direction
  110. \param bot coordinate of fringe bottom
  111. \param surf surface (geosurf)
  112. \param row row along which is fringe drawn
  113. \param side
  114. */
  115. void gsd_fringe_horiz_poly(float bot, geosurf * surf, int row, int side)
  116. {
  117. int col;
  118. float pt[4];
  119. typbuff *buff;
  120. long offset;
  121. int xcnt;
  122. int row_shift, max_row_shift;
  123. max_row_shift = 20;
  124. GS_set_draw(GSD_FRONT);
  125. gsd_pushmatrix();
  126. gsd_do_scale(1);
  127. gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
  128. buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
  129. xcnt = VCOLS(surf);
  130. gsd_bgnqstrip();
  131. col = 0;
  132. /* floor left */
  133. pt[X] = col * (surf->x_mod * surf->xres);
  134. pt[Y] =
  135. ((surf->rows - 1) * surf->yres) -
  136. ((row + side) * (surf->y_mod * surf->yres));
  137. pt[Z] = bot;
  138. gsd_vert_func(pt);
  139. offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
  140. /* find nearest row with defined z coordinate */
  141. row_shift = 0;
  142. while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
  143. row_shift++;
  144. if (side)
  145. offset = ((row - row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
  146. else
  147. offset = ((row + row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
  148. }
  149. pt[Z] = pt[Z] * surf->z_exag;
  150. gsd_vert_func(pt);
  151. for (col = 0; col < xcnt - 1; col++) {
  152. /* bottom vertex */
  153. pt[X] = col * (surf->x_mod * surf->xres);
  154. pt[Y] =
  155. ((surf->rows - 1) * surf->yres) -
  156. ((row + side) * (surf->y_mod * surf->yres));
  157. pt[Z] = bot;
  158. gsd_vert_func(pt);
  159. /* map vertex */
  160. offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
  161. row_shift = 0;
  162. while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
  163. row_shift++;
  164. if (side)
  165. offset = ((row - row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
  166. else
  167. offset = ((row + row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
  168. }
  169. pt[Z] = pt[Z] * surf->z_exag;
  170. gsd_vert_func(pt);
  171. }
  172. gsd_endqstrip();
  173. GS_done_draw();
  174. gsd_popmatrix();
  175. gsd_flush();
  176. return;
  177. }
  178. /*!
  179. \brief Draw fringe outline in x direction
  180. \param bot coordinate of fringe bottom
  181. \param surf surface (geosurf)
  182. \param row row along which is fringe drawn
  183. \param side
  184. */
  185. void gsd_fringe_horiz_line(float bot, geosurf * surf, int row, int side)
  186. {
  187. int col;
  188. float pt[4];
  189. typbuff *buff;
  190. long offset;
  191. int xcnt;
  192. int row_shift, max_row_shift;
  193. max_row_shift = 20;
  194. GS_set_draw(GSD_FRONT);
  195. gsd_pushmatrix();
  196. gsd_do_scale(1);
  197. gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
  198. buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
  199. xcnt = VCOLS(surf);
  200. gsd_bgnline();
  201. col = 0;
  202. /* floor left */
  203. pt[X] = col * (surf->x_mod * surf->xres);
  204. pt[Y] =
  205. ((surf->rows - 1) * surf->yres) -
  206. ((row + side) * (surf->y_mod * surf->yres));
  207. pt[Z] = bot;
  208. gsd_vert_func(pt);
  209. /* find nearest row with defined z coordinate */
  210. offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
  211. row_shift = 0;
  212. while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
  213. row_shift++;
  214. if (side)
  215. offset = ((row - row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
  216. else
  217. offset = ((row + row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
  218. }
  219. pt[Z] = pt[Z] * surf->z_exag;
  220. gsd_vert_func(pt);
  221. for (col = 0; col < xcnt - 1; col++) {
  222. /* bottom right */
  223. pt[X] = col * (surf->x_mod * surf->xres);
  224. pt[Y] =
  225. ((surf->rows - 1) * surf->yres) -
  226. ((row + side) * (surf->y_mod * surf->yres));
  227. offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
  228. row_shift = 0;
  229. while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
  230. row_shift++;
  231. if (side)
  232. offset = ((row - row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
  233. else
  234. offset = ((row + row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
  235. }
  236. pt[Z] = pt[Z] * surf->z_exag;
  237. gsd_vert_func(pt);
  238. }
  239. col--;
  240. pt[X] = col * (surf->x_mod * surf->xres);
  241. pt[Y] =
  242. ((surf->rows - 1) * surf->yres) -
  243. ((row + side) * (surf->y_mod * surf->yres));
  244. pt[Z] = bot;
  245. gsd_vert_func(pt);
  246. col = 0;
  247. pt[X] = col * (surf->x_mod * surf->xres);
  248. pt[Y] =
  249. ((surf->rows - 1) * surf->yres) -
  250. ((row + side) * (surf->y_mod * surf->yres));
  251. pt[Z] = bot;
  252. gsd_vert_func(pt);
  253. gsd_endline();
  254. GS_done_draw();
  255. gsd_popmatrix();
  256. gsd_flush();
  257. return;
  258. }
  259. /*!
  260. \brief Draw fringe outline in y direction
  261. \param bot coordinate of fringe bottom
  262. \param surf surface (geosurf)
  263. \param col column along which is fringe drawn
  264. \param side
  265. */
  266. void gsd_fringe_vert_poly(float bot, geosurf * surf, int col, int side)
  267. {
  268. int row;
  269. float pt[4];
  270. typbuff *buff;
  271. long offset;
  272. int ycnt;
  273. int col_shift, max_col_shift;
  274. max_col_shift = 20;
  275. GS_set_draw(GSD_FRONT);
  276. gsd_pushmatrix();
  277. gsd_do_scale(1);
  278. gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
  279. gsd_bgnqstrip();
  280. buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
  281. ycnt = VROWS(surf);
  282. row = 0;
  283. /* floor left */
  284. pt[X] = col * (surf->x_mod * surf->xres);
  285. pt[Y] =
  286. ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
  287. pt[Z] = bot;
  288. gsd_vert_func(pt);
  289. /* find nearest row with defined z coordinate */
  290. offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
  291. col_shift = 0;
  292. while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
  293. col_shift++;
  294. if (side)
  295. offset = (row * surf->y_mod * surf->cols) + ((col - col_shift) * surf->x_mod);
  296. else
  297. offset = (row * surf->y_mod * surf->cols) + ((col + col_shift) * surf->x_mod);
  298. }
  299. pt[Z] = pt[Z] * surf->z_exag;
  300. gsd_vert_func(pt);
  301. for (row = 0; row < ycnt - 1; row++) {
  302. /* floor */
  303. pt[X] = col * (surf->x_mod * surf->xres);
  304. pt[Y] =
  305. ((surf->rows - 1) * surf->yres) -
  306. (row * (surf->y_mod * surf->yres));
  307. pt[Z] = bot;
  308. gsd_vert_func(pt);
  309. /* map elevation */
  310. offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
  311. col_shift = 0;
  312. while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
  313. col_shift++;
  314. if (side)
  315. offset = (row * surf->y_mod * surf->cols) + ((col - col_shift) * surf->x_mod);
  316. else
  317. offset = (row * surf->y_mod * surf->cols) + ((col + col_shift) * surf->x_mod);
  318. }
  319. pt[Z] = pt[Z] * surf->z_exag;
  320. gsd_vert_func(pt);
  321. }
  322. gsd_endqstrip();
  323. GS_done_draw();
  324. gsd_popmatrix();
  325. gsd_flush();
  326. return;
  327. }
  328. /*!
  329. \brief Draw fringe outline in y direction
  330. \param bot coordinate of fringe bottom
  331. \param surf surface (geosurf)
  332. \param col column along which is fringe drawn
  333. \param side
  334. */
  335. void gsd_fringe_vert_line(float bot, geosurf * surf, int col, int side)
  336. {
  337. int row;
  338. float pt[4];
  339. typbuff *buff;
  340. long offset;
  341. int ycnt;
  342. int col_shift, max_col_shift;
  343. max_col_shift = 20;
  344. GS_set_draw(GSD_FRONT);
  345. gsd_pushmatrix();
  346. gsd_do_scale(1);
  347. gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
  348. buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
  349. ycnt = VROWS(surf);
  350. gsd_bgnline();
  351. row = 0;
  352. /* floor left */
  353. pt[X] = col * (surf->x_mod * surf->xres);
  354. pt[Y] =
  355. ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
  356. pt[Z] = bot;
  357. gsd_vert_func(pt);
  358. /* find nearest row with defined z coordinate */
  359. offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
  360. col_shift = 0;
  361. while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
  362. col_shift++;
  363. if (side)
  364. offset = (row * surf->y_mod * surf->cols) + ((col - col_shift) * surf->x_mod);
  365. else
  366. offset = (row * surf->y_mod * surf->cols) + ((col + col_shift) * surf->x_mod);
  367. }
  368. pt[Z] = pt[Z] * surf->z_exag;
  369. gsd_vert_func(pt);
  370. for (row = 0; row < ycnt - 1; row++) {
  371. /* bottom right */
  372. pt[X] = col * (surf->x_mod * surf->xres);
  373. pt[Y] =
  374. ((surf->rows - 1) * surf->yres) -
  375. (row * (surf->y_mod * surf->yres));
  376. offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
  377. col_shift = 0;
  378. while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
  379. col_shift++;
  380. if (side)
  381. offset = (row * surf->y_mod * surf->cols) + ((col - col_shift) * surf->x_mod);
  382. else
  383. offset = (row * surf->y_mod * surf->cols) + ((col + col_shift) * surf->x_mod);
  384. }
  385. pt[Z] = pt[Z] * surf->z_exag;
  386. gsd_vert_func(pt);
  387. }
  388. row--;
  389. pt[X] = col * (surf->x_mod * surf->xres);
  390. pt[Y] =
  391. ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
  392. pt[Z] = bot;
  393. gsd_vert_func(pt);
  394. row = 0;
  395. pt[X] = col * (surf->x_mod * surf->xres);
  396. pt[Y] =
  397. ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
  398. pt[Z] = bot;
  399. gsd_vert_func(pt);
  400. gsd_endline();
  401. GS_done_draw();
  402. gsd_popmatrix();
  403. gsd_flush();
  404. return;
  405. }
  406. /*!
  407. \brief ADD
  408. \param bot
  409. \param surf surface (geosurf)
  410. \param row
  411. \param side
  412. */
  413. void gsd_fringe_horiz_line2(float bot, geosurf * surf, int row, int side)
  414. {
  415. int col;
  416. int cnt;
  417. float pt[4];
  418. typbuff *buff;
  419. long offset;
  420. int xcnt;
  421. GS_set_draw(GSD_FRONT);
  422. gsd_pushmatrix();
  423. gsd_do_scale(1);
  424. gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
  425. buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
  426. xcnt = VCOLS(surf);
  427. gsd_bgnline();
  428. col = 0;
  429. /* floor left */
  430. pt[X] = surf->xmin + (col * (surf->x_mod * surf->xres));
  431. pt[Y] = surf->ymax - ((row + side) * (surf->y_mod * surf->yres));
  432. pt[Z] = bot;
  433. gsd_vert_func(pt);
  434. offset = 0;
  435. GET_MAPATT(buff, offset, pt[Z]);
  436. pt[Z] = pt[Z] * surf->z_exag;
  437. gsd_vert_func(pt);
  438. cnt = 1;
  439. for (col = 0; col < xcnt - 1; col++) {
  440. /* bottom right */
  441. pt[X] = surf->xmin + (col * (surf->x_mod * surf->xres));
  442. pt[Y] = surf->ymax - ((row + side) * (surf->y_mod * surf->yres));
  443. offset = col * surf->x_mod;
  444. GET_MAPATT(buff, offset, pt[Z]);
  445. pt[Z] = pt[Z] * surf->z_exag;
  446. gsd_vert_func(pt);
  447. cnt++;
  448. }
  449. col--;
  450. pt[X] = surf->xmin + (col * (surf->x_mod * surf->xres));
  451. pt[Y] = surf->ymax - ((row + side) * (surf->y_mod * surf->yres));
  452. pt[Z] = bot;
  453. gsd_vert_func(pt);
  454. gsd_endline();
  455. GS_done_draw();
  456. gsd_popmatrix();
  457. gsd_flush();
  458. return;
  459. }