GRASS GIS 8 Programmer's Manual 8.2.1RC1(2022)-exported
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 */
32float Nnorth[] = { 0.0, 0.8, 0.6 };
33float Nsouth[] = { 0.0, -0.8, 0.6 };
34float Neast[] = { 0.8, 0.0, 0.6 };
35float Nwest[] = { -0.8, 0.0, 0.6 };
36float Ntop[] = { 0.0, 0.0, 1.0 };
37float 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 */
51void 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
74 gsd_colormode(CM_COLOR);
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 */
141void 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
152 GS_set_draw(GSD_FRONT);
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
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
209
210 GS_done_draw();
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 */
225void 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
236 GS_set_draw(GSD_FRONT);
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();
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 */
321void 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
333 GS_set_draw(GSD_FRONT);
335 gsd_do_scale(1);
336 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
337
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
387
388 GS_done_draw();
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 */
403void 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
414 GS_set_draw(GSD_FRONT);
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();
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 */
495void 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
504 GS_set_draw(GSD_FRONT);
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();
547 gsd_flush();
548
549 return;
550}
void GS_set_draw(int where)
Sets which buffer to draw to.
Definition: gs2.c:2462
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2501
typbuff * gs_get_att_typbuff(geosurf *gs, int desc, int to_write)
Get attribute data buffer.
Definition: gs.c:681
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:321
#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:403
void gsd_fringe_horiz_line(float bot, geosurf *surf, int row, int side)
Draw fringe outline in x direction.
Definition: gsd_fringe.c:225
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:495
float Neast[]
Definition: gsd_fringe.c:34
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:510
void gsd_zwritemask(unsigned long n)
Write out z-mask.
Definition: gsd_prim.c:240
void gsd_vert_func(float *pt)
ADD.
Definition: gsd_prim.c:689
void gsd_bgnqstrip(void)
ADD.
Definition: gsd_prim.c:276
void gsd_colormode(int cm)
Set color mode.
Definition: gsd_prim.c:97
void gsd_endqstrip(void)
ADD.
Definition: gsd_prim.c:286
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:500
void gsd_flush(void)
Mostly for flushing drawing commands across a network.
Definition: gsd_prim.c:83
void gsd_endline(void)
End line.
Definition: gsd_prim.c:406
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:396
void gsd_translate(float dx, float dy, float dz)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:538
void gsd_color_func(unsigned int col)
Set current color.
Definition: gsd_prim.c:701
void gsd_linewidth(short n)
Set width of rasterized lines.
Definition: gsd_prim.c:266
void gsd_do_scale(int doexag)
Set current scale.
Definition: gsd_views.c:355
#define GET_MAPATT(buff, offset, att)
Definition: gsget.h:27
#define VCOLS(gs)
Definition: rowcol.h:14
#define VROWS(gs)
Definition: rowcol.h:13
#define X(j)
#define Y(j)