GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
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  float xmax, ymax;
57 
58  xres = surf->x_mod * surf->xres;
59  yres = surf->y_mod * surf->yres;
60 
61  xcnt = VCOLS(surf);
62  ycnt = VROWS(surf);
63 
64  xmax = surf->xmax;
65  ymax = surf->ymax;
66 
67  /*
68  bot = surf->zmin - ((surf->zrange/4.) * surf->z_exag);
69  */
70  bot = elev - ((surf->zrange / 4.) * surf->z_exag);
71 
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] =
166  ((surf->rows - 1) * surf->yres) -
167  ((row + side) * (surf->y_mod * surf->yres));
168  pt[Z] = bot;
169  gsd_vert_func(pt);
170 
171  offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
172 
173  /* find nearest row with defined z coordinate */
174  row_shift = 0;
175  while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
176  row_shift++;
177  if (side)
178  offset = ((row - row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
179  else
180  offset = ((row + row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
181  }
182  pt[Z] = pt[Z] * surf->z_exag;
183  gsd_vert_func(pt);
184 
185  for (col = 0; col < xcnt - 1; col++) {
186  /* bottom vertex */
187  pt[X] = col * (surf->x_mod * surf->xres);
188  pt[Y] =
189  ((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) + (col * surf->x_mod);
201  else
202  offset = ((row + row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
203  }
204  pt[Z] = pt[Z] * surf->z_exag;
205  gsd_vert_func(pt);
206  }
207 
208  gsd_endqstrip();
209 
210  GS_done_draw();
211  gsd_popmatrix();
212  gsd_flush();
213 
214  return;
215 }
216 
217 /*!
218  \brief Draw fringe outline in x direction
219 
220  \param bot coordinate of fringe bottom
221  \param surf surface (geosurf)
222  \param row row along which is fringe drawn
223  \param side
224  */
225 void gsd_fringe_horiz_line(float bot, geosurf * surf, int row, int side)
226 {
227  int col;
228  float pt[4];
229  typbuff *buff;
230  long offset;
231  int xcnt;
232  int row_shift, max_row_shift;
233 
234  max_row_shift = 20;
235 
237  gsd_pushmatrix();
238  gsd_do_scale(1);
239  gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
240 
241 
242  buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
243  xcnt = VCOLS(surf);
244 
245  gsd_bgnline();
246 
247  col = 0;
248  /* floor left */
249  pt[X] = col * (surf->x_mod * surf->xres);
250  pt[Y] =
251  ((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) + (col * surf->x_mod);
263  else
264  offset = ((row + row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
265  }
266  pt[Z] = pt[Z] * surf->z_exag;
267  gsd_vert_func(pt);
268 
269  for (col = 0; col < xcnt - 1; col++) {
270  /* bottom right */
271  pt[X] = col * (surf->x_mod * surf->xres);
272  pt[Y] =
273  ((surf->rows - 1) * surf->yres) -
274  ((row + side) * (surf->y_mod * surf->yres));
275  offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
276  row_shift = 0;
277  while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
278  row_shift++;
279  if (side)
280  offset = ((row - row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
281  else
282  offset = ((row + row_shift) * surf->y_mod * surf->cols) + (col * surf->x_mod);
283  }
284  pt[Z] = pt[Z] * surf->z_exag;
285  gsd_vert_func(pt);
286  }
287 
288  col--;
289  pt[X] = col * (surf->x_mod * surf->xres);
290  pt[Y] =
291  ((surf->rows - 1) * surf->yres) -
292  ((row + side) * (surf->y_mod * surf->yres));
293  pt[Z] = bot;
294  gsd_vert_func(pt);
295 
296  col = 0;
297  pt[X] = col * (surf->x_mod * surf->xres);
298  pt[Y] =
299  ((surf->rows - 1) * surf->yres) -
300  ((row + side) * (surf->y_mod * surf->yres));
301  pt[Z] = bot;
302  gsd_vert_func(pt);
303 
304  gsd_endline();
305 
306  GS_done_draw();
307  gsd_popmatrix();
308  gsd_flush();
309 
310  return;
311 }
312 
313 /*!
314  \brief Draw fringe outline in y direction
315 
316  \param bot coordinate of fringe bottom
317  \param surf surface (geosurf)
318  \param col column along which is fringe drawn
319  \param side
320  */
321 void gsd_fringe_vert_poly(float bot, geosurf * surf, int col, int side)
322 {
323 
324  int row;
325  float pt[4];
326  typbuff *buff;
327  long offset;
328  int ycnt;
329  int col_shift, max_col_shift;
330 
331  max_col_shift = 20;
332 
334  gsd_pushmatrix();
335  gsd_do_scale(1);
336  gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
337 
338  gsd_bgnqstrip();
339 
340  buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
341  ycnt = VROWS(surf);
342 
343  row = 0;
344  /* floor left */
345  pt[X] = col * (surf->x_mod * surf->xres);
346  pt[Y] =
347  ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
348  pt[Z] = bot;
349  gsd_vert_func(pt);
350 
351  /* find nearest row with defined z coordinate */
352  offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
353  col_shift = 0;
354  while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
355  col_shift++;
356  if (side)
357  offset = (row * surf->y_mod * surf->cols) + ((col - col_shift) * surf->x_mod);
358  else
359  offset = (row * surf->y_mod * surf->cols) + ((col + col_shift) * surf->x_mod);
360  }
361  pt[Z] = pt[Z] * surf->z_exag;
362  gsd_vert_func(pt);
363 
364  for (row = 0; row < ycnt - 1; row++) {
365  /* floor */
366  pt[X] = col * (surf->x_mod * surf->xres);
367  pt[Y] =
368  ((surf->rows - 1) * surf->yres) -
369  (row * (surf->y_mod * surf->yres));
370  pt[Z] = bot;
371  gsd_vert_func(pt);
372  /* map elevation */
373  offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
374  col_shift = 0;
375  while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
376  col_shift++;
377  if (side)
378  offset = (row * surf->y_mod * surf->cols) + ((col - col_shift) * surf->x_mod);
379  else
380  offset = (row * surf->y_mod * surf->cols) + ((col + col_shift) * surf->x_mod);
381  }
382  pt[Z] = pt[Z] * surf->z_exag;
383  gsd_vert_func(pt);
384  }
385 
386  gsd_endqstrip();
387 
388  GS_done_draw();
389  gsd_popmatrix();
390  gsd_flush();
391 
392  return;
393 }
394 
395 /*!
396  \brief Draw fringe outline in y direction
397 
398  \param bot coordinate of fringe bottom
399  \param surf surface (geosurf)
400  \param col column along which is fringe drawn
401  \param side
402  */
403 void gsd_fringe_vert_line(float bot, geosurf * surf, int col, int side)
404 {
405  int row;
406  float pt[4];
407  typbuff *buff;
408  long offset;
409  int ycnt;
410  int col_shift, max_col_shift;
411 
412  max_col_shift = 20;
413 
415  gsd_pushmatrix();
416  gsd_do_scale(1);
417  gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
418 
419 
420  buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
421  ycnt = VROWS(surf);
422  gsd_bgnline();
423 
424  row = 0;
425  /* floor left */
426  pt[X] = col * (surf->x_mod * surf->xres);
427  pt[Y] =
428  ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
429  pt[Z] = bot;
430  gsd_vert_func(pt);
431 
432  /* find nearest row with defined z coordinate */
433  offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
434  col_shift = 0;
435  while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
436  col_shift++;
437  if (side)
438  offset = (row * surf->y_mod * surf->cols) + ((col - col_shift) * surf->x_mod);
439  else
440  offset = (row * surf->y_mod * surf->cols) + ((col + col_shift) * surf->x_mod);
441  }
442  pt[Z] = pt[Z] * surf->z_exag;
443  gsd_vert_func(pt);
444 
445  for (row = 0; row < ycnt - 1; row++) {
446  /* bottom right */
447  pt[X] = col * (surf->x_mod * surf->xres);
448  pt[Y] =
449  ((surf->rows - 1) * surf->yres) -
450  (row * (surf->y_mod * surf->yres));
451  offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
452  col_shift = 0;
453  while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
454  col_shift++;
455  if (side)
456  offset = (row * surf->y_mod * surf->cols) + ((col - col_shift) * surf->x_mod);
457  else
458  offset = (row * surf->y_mod * surf->cols) + ((col + col_shift) * surf->x_mod);
459  }
460  pt[Z] = pt[Z] * surf->z_exag;
461  gsd_vert_func(pt);
462  }
463 
464  row--;
465  pt[X] = col * (surf->x_mod * surf->xres);
466  pt[Y] =
467  ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
468  pt[Z] = bot;
469  gsd_vert_func(pt);
470 
471  row = 0;
472  pt[X] = col * (surf->x_mod * surf->xres);
473  pt[Y] =
474  ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
475  pt[Z] = bot;
476  gsd_vert_func(pt);
477 
478  gsd_endline();
479 
480  GS_done_draw();
481  gsd_popmatrix();
482  gsd_flush();
483 
484  return;
485 }
486 
487 /*!
488  \brief ADD
489 
490  \param bot
491  \param surf surface (geosurf)
492  \param row
493  \param side
494  */
495 void gsd_fringe_horiz_line2(float bot, geosurf * surf, int row, int side)
496 {
497  int col;
498  int cnt;
499  float pt[4];
500  typbuff *buff;
501  long offset;
502  int xcnt;
503 
505  gsd_pushmatrix();
506  gsd_do_scale(1);
507  gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
508 
509  buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
510  xcnt = VCOLS(surf);
511  gsd_bgnline();
512 
513  col = 0;
514  /* floor left */
515  pt[X] = surf->xmin + (col * (surf->x_mod * surf->xres));
516  pt[Y] = surf->ymax - ((row + side) * (surf->y_mod * surf->yres));
517  pt[Z] = bot;
518  gsd_vert_func(pt);
519 
520  offset = 0;
521  GET_MAPATT(buff, offset, pt[Z]);
522  pt[Z] = pt[Z] * surf->z_exag;
523  gsd_vert_func(pt);
524 
525  cnt = 1;
526  for (col = 0; col < xcnt - 1; col++) {
527  /* bottom right */
528  pt[X] = surf->xmin + (col * (surf->x_mod * surf->xres));
529  pt[Y] = surf->ymax - ((row + side) * (surf->y_mod * surf->yres));
530  offset = col * surf->x_mod;
531  GET_MAPATT(buff, offset, pt[Z]);
532  pt[Z] = pt[Z] * surf->z_exag;
533  gsd_vert_func(pt);
534  cnt++;
535  }
536 
537  col--;
538  pt[X] = surf->xmin + (col * (surf->x_mod * surf->xres));
539  pt[Y] = surf->ymax - ((row + side) * (surf->y_mod * surf->yres));
540  pt[Z] = bot;
541  gsd_vert_func(pt);
542 
543  gsd_endline();
544 
545  GS_done_draw();
546  gsd_popmatrix();
547  gsd_flush();
548 
549  return;
550 }
void gsd_flush(void)
Mostly for flushing drawing commands across a network.
Definition: gsd_prim.c:83
#define VROWS(gs)
Definition: rowcol.h:13
int rows
Definition: ogsf.h:260
float xmax
Definition: ogsf.h:268
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:500
#define VCOLS(gs)
Definition: rowcol.h:14
#define ATT_TOPO
Definition: ogsf.h:73
float Nwest[]
Definition: gsd_fringe.c:35
float Neast[]
Definition: gsd_fringe.c:34
#define FRINGE_FORE
Definition: gsd_fringe.c:26
#define FRINGE_WIDTH
Definition: gsd_fringe.c:27
float Nnorth[]
Normals.
Definition: gsd_fringe.c:32
float z_exag
Definition: ogsf.h:266
float zrange
Definition: ogsf.h:269
int cols
Definition: ogsf.h:260
void gsd_fringe_vert_poly(float bot, geosurf *surf, int col, int side)
Draw fringe outline in y direction.
Definition: gsd_fringe.c:321
void gsd_colormode(int)
Set color mode.
Definition: gsd_prim.c:97
double yres
Definition: ogsf.h:265
int x_mod
Definition: ogsf.h:271
float x_trans
Definition: ogsf.h:267
#define CM_COLOR
Definition: ogsf.h:145
void gsd_color_func(unsigned int)
Set current color.
Definition: gsd_prim.c:701
void gsd_endline(void)
End line.
Definition: gsd_prim.c:406
void gsd_bgnqstrip(void)
ADD.
Definition: gsd_prim.c:276
void gsd_fringe_horiz_poly(float bot, geosurf *surf, int row, int side)
Draw fringe polygon in x direction.
Definition: gsd_fringe.c:141
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:538
int y_mod
Definition: ogsf.h:271
void gsd_fringe_horiz_line(float bot, geosurf *surf, int row, int side)
Draw fringe outline in x direction.
Definition: gsd_fringe.c:225
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2501
#define Z
Definition: ogsf.h:139
void gsd_zwritemask(unsigned long)
Write out z-mask.
Definition: gsd_prim.c:240
float y_trans
Definition: ogsf.h:267
typbuff * gs_get_att_typbuff(geosurf *, int, int)
Get attribute data buffer.
Definition: gs.c:681
#define Y
Definition: ogsf.h:138
float xmin
Definition: ogsf.h:268
void gsd_linewidth(short)
Set width of rasterized lines.
Definition: gsd_prim.c:266
float Nsouth[]
Definition: gsd_fringe.c:33
float ymax
Definition: ogsf.h:268
Definition: ogsf.h:204
#define GSD_FRONT
Definition: ogsf.h:101
float Nbottom[]
Definition: gsd_fringe.c:37
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:510
#define X
Definition: ogsf.h:137
void gsd_display_fringe(geosurf *surf, unsigned long clr, float elev, int where[4])
Display fridge.
Definition: gsd_fringe.c:51
float z_trans
Definition: ogsf.h:267
double xres
Definition: ogsf.h:265
void gsd_fringe_vert_line(float bot, geosurf *surf, int col, int side)
Draw fringe outline in y direction.
Definition: gsd_fringe.c:403
void GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2462
void gsd_do_scale(int)
Set current scale.
Definition: gsd_views.c:355
Definition: ogsf.h:257
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:396
void gsd_fringe_horiz_line2(float bot, geosurf *surf, int row, int side)
ADD.
Definition: gsd_fringe.c:495
void gsd_endqstrip(void)
ADD.
Definition: gsd_prim.c:286
float Ntop[]
Definition: gsd_fringe.c:36
#define GET_MAPATT(buff, offset, att)
Definition: gsget.h:27
void gsd_vert_func(float *)
ADD.
Definition: gsd_prim.c:689