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