GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
Loading...
Searching...
No Matches
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 SPDX-FileCopyrightText: 1999-2008 GRASS Development Team
11 SPDX-License-Identifier: GPL-2.0-or-later
12
13 \author Bill Brown USACERL, GMSL/University of Illinois
14 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
15 */
16
17#include <grass/ogsf.h>
18
19#include "gsget.h"
20#include "rowcol.h"
21
22#define FRINGE_FORE 0x000000
23#define FRINGE_WIDTH 2
24
25/*!
26 \brief Normals
27 */
28float Nnorth[] = {0.0, 0.8, 0.6};
29float Nsouth[] = {0.0, -0.8, 0.6};
30float Neast[] = {0.8, 0.0, 0.6};
31float Nwest[] = {-0.8, 0.0, 0.6};
32float Ntop[] = {0.0, 0.0, 1.0};
33float Nbottom[] = {0.0, 0.0, -1.0};
34
35/*!
36 \brief Display fridge
37
38 \todo add elevation for bottom
39 add color option
40 add ruler grid lines
41
42 \param surf surface (geosurf)
43 \param clr
44 \param elev
45 \param where
46 */
47void gsd_display_fringe(geosurf *surf, unsigned long clr, float elev,
48 int where[4])
49{
50 float bot /*, xres, yres */; /* world size of view cell */
51 int ycnt, xcnt; /* number of view cells across */
52
53 /* float xmax, ymax; */
54
55 /* xres = surf->x_mod * surf->xres; */
56 /* yres = surf->y_mod * surf->yres; */
57
58 xcnt = VCOLS(surf);
59 ycnt = VROWS(surf);
60
61 /* xmax = surf->xmax; */
62 /* ymax = surf->ymax; */
63
64 /*
65 bot = surf->zmin - ((surf->zrange/4.) * surf->z_exag);
66 */
67 bot = elev - ((surf->zrange / 4.) * surf->z_exag);
68
71
72 /* North fringe */
73 if (where[0] || where[1]) {
76 gsd_zwritemask(0x0);
77 gsd_fringe_horiz_poly(bot, surf, 0, 0);
78 gsd_color_func(FRINGE_FORE); /* WHITE */
79 gsd_fringe_horiz_line(bot, surf, 0, 0);
80 gsd_zwritemask(0xffffffff);
81 /* wmpack (0); ??? glColorMask */
83 gsd_fringe_horiz_poly(bot, surf, 0, 0);
84 }
85
86 /* South fringe */
87 if (where[2] || where[3]) {
90 gsd_zwritemask(0x0);
91 gsd_fringe_horiz_poly(bot, surf, ycnt - 2, 1);
92 gsd_color_func(FRINGE_FORE); /* WHITE */
93 gsd_fringe_horiz_line(bot, surf, ycnt - 2, 1);
94 gsd_zwritemask(0xffffffff);
95 /* wmpack (0); ??? glColorMask */
97 gsd_fringe_horiz_poly(bot, surf, ycnt - 2, 1);
98 }
99
100 /* West fringe */
101 if (where[0] || where[2]) {
104 gsd_zwritemask(0x0);
105 gsd_fringe_vert_poly(bot, surf, 0, 0);
107 gsd_fringe_vert_line(bot, surf, 0, 0);
108 gsd_zwritemask(0xffffffff);
110 gsd_fringe_vert_poly(bot, surf, 0, 0);
111 }
112
113 /* East fringe */
114 if (where[1] || where[3]) {
117 gsd_zwritemask(0x0);
118 gsd_fringe_vert_poly(bot, surf, xcnt - 2, 1);
120 gsd_fringe_vert_line(bot, surf, xcnt - 2, 1);
121 gsd_zwritemask(0xffffffff);
123 gsd_fringe_vert_poly(bot, surf, xcnt - 2, 1);
124 }
125
126 return;
127}
128
129/*!
130 \brief Draw fringe polygon in x direction
131
132 \param bot coordinate of fringe bottom
133 \param surf surface (geosurf)
134 \param row row along which is fringe drawn
135 \param side
136 */
137void gsd_fringe_horiz_poly(float bot, geosurf *surf, int row, int side)
138{
139 int col;
140 float pt[4];
141 typbuff *buff;
142 long offset;
143 int xcnt;
145
146 max_row_shift = 20;
147
150 gsd_do_scale(1);
151 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
152
153 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
154 xcnt = VCOLS(surf);
155
157
158 col = 0;
159 /* floor left */
160 pt[X] = col * (surf->x_mod * surf->xres);
161 pt[Y] = ((surf->rows - 1) * surf->yres) -
162 ((row + side) * (surf->y_mod * surf->yres));
163 pt[Z] = bot;
165
166 offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
167
168 /* find nearest row with defined z coordinate */
169 row_shift = 0;
170 while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
171 row_shift++;
172 if (side)
173 offset = ((row - row_shift) * surf->y_mod * surf->cols) +
174 (col * surf->x_mod);
175 else
176 offset = ((row + row_shift) * surf->y_mod * surf->cols) +
177 (col * surf->x_mod);
178 }
179 pt[Z] = pt[Z] * surf->z_exag;
181
182 for (col = 0; col < xcnt - 1; col++) {
183 /* bottom vertex */
184 pt[X] = col * (surf->x_mod * surf->xres);
185 pt[Y] = ((surf->rows - 1) * surf->yres) -
186 ((row + side) * (surf->y_mod * surf->yres));
187 pt[Z] = bot;
189
190 /* map vertex */
191 offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
192 row_shift = 0;
193 while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
194 row_shift++;
195 if (side)
196 offset = ((row - row_shift) * surf->y_mod * surf->cols) +
197 (col * surf->x_mod);
198 else
199 offset = ((row + row_shift) * surf->y_mod * surf->cols) +
200 (col * surf->x_mod);
201 }
202 pt[Z] = pt[Z] * surf->z_exag;
204 }
205
207
208 GS_done_draw();
210 gsd_flush();
211
212 return;
213}
214
215/*!
216 \brief Draw fringe outline in x direction
217
218 \param bot coordinate of fringe bottom
219 \param surf surface (geosurf)
220 \param row row along which is fringe drawn
221 \param side
222 */
223void gsd_fringe_horiz_line(float bot, geosurf *surf, int row, int side)
224{
225 int col;
226 float pt[4];
227 typbuff *buff;
228 long offset;
229 int xcnt;
231
232 max_row_shift = 20;
233
236 gsd_do_scale(1);
237 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
238
239 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
240 xcnt = VCOLS(surf);
241
242 gsd_bgnline();
243
244 col = 0;
245 /* floor left */
246 pt[X] = col * (surf->x_mod * surf->xres);
247 pt[Y] = ((surf->rows - 1) * surf->yres) -
248 ((row + side) * (surf->y_mod * surf->yres));
249 pt[Z] = bot;
251
252 /* find nearest row with defined z coordinate */
253 offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
254 row_shift = 0;
255 while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
256 row_shift++;
257 if (side)
258 offset = ((row - row_shift) * surf->y_mod * surf->cols) +
259 (col * surf->x_mod);
260 else
261 offset = ((row + row_shift) * surf->y_mod * surf->cols) +
262 (col * surf->x_mod);
263 }
264 pt[Z] = pt[Z] * surf->z_exag;
266
267 for (col = 0; col < xcnt - 1; col++) {
268 /* bottom right */
269 pt[X] = col * (surf->x_mod * surf->xres);
270 pt[Y] = ((surf->rows - 1) * surf->yres) -
271 ((row + side) * (surf->y_mod * surf->yres));
272 offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
273 row_shift = 0;
274 while (!GET_MAPATT(buff, offset, pt[Z]) && row_shift < max_row_shift) {
275 row_shift++;
276 if (side)
277 offset = ((row - row_shift) * surf->y_mod * surf->cols) +
278 (col * surf->x_mod);
279 else
280 offset = ((row + row_shift) * surf->y_mod * surf->cols) +
281 (col * surf->x_mod);
282 }
283 pt[Z] = pt[Z] * surf->z_exag;
285 }
286
287 col--;
288 pt[X] = col * (surf->x_mod * surf->xres);
289 pt[Y] = ((surf->rows - 1) * surf->yres) -
290 ((row + side) * (surf->y_mod * surf->yres));
291 pt[Z] = bot;
293
294 col = 0;
295 pt[X] = col * (surf->x_mod * surf->xres);
296 pt[Y] = ((surf->rows - 1) * surf->yres) -
297 ((row + side) * (surf->y_mod * surf->yres));
298 pt[Z] = bot;
300
301 gsd_endline();
302
303 GS_done_draw();
305 gsd_flush();
306
307 return;
308}
309
310/*!
311 \brief Draw fringe outline in y direction
312
313 \param bot coordinate of fringe bottom
314 \param surf surface (geosurf)
315 \param col column along which is fringe drawn
316 \param side
317 */
318void gsd_fringe_vert_poly(float bot, geosurf *surf, int col, int side)
319{
320
321 int row;
322 float pt[4];
323 typbuff *buff;
324 long offset;
325 int ycnt;
327
328 max_col_shift = 20;
329
332 gsd_do_scale(1);
333 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
334
336
337 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
338 ycnt = VROWS(surf);
339
340 row = 0;
341 /* floor left */
342 pt[X] = col * (surf->x_mod * surf->xres);
343 pt[Y] =
344 ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
345 pt[Z] = bot;
347
348 /* find nearest row with defined z coordinate */
349 offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
350 col_shift = 0;
351 while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
352 col_shift++;
353 if (side)
354 offset = (row * surf->y_mod * surf->cols) +
355 ((col - col_shift) * surf->x_mod);
356 else
357 offset = (row * surf->y_mod * surf->cols) +
358 ((col + col_shift) * surf->x_mod);
359 }
360 pt[Z] = pt[Z] * surf->z_exag;
362
363 for (row = 0; row < ycnt - 1; row++) {
364 /* floor */
365 pt[X] = col * (surf->x_mod * surf->xres);
366 pt[Y] = ((surf->rows - 1) * surf->yres) -
367 (row * (surf->y_mod * surf->yres));
368 pt[Z] = bot;
370 /* map elevation */
371 offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
372 col_shift = 0;
373 while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
374 col_shift++;
375 if (side)
376 offset = (row * surf->y_mod * surf->cols) +
377 ((col - col_shift) * surf->x_mod);
378 else
379 offset = (row * surf->y_mod * surf->cols) +
380 ((col + col_shift) * surf->x_mod);
381 }
382 pt[Z] = pt[Z] * surf->z_exag;
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;
411
412 max_col_shift = 20;
413
416 gsd_do_scale(1);
417 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
418
419 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
420 ycnt = VROWS(surf);
421 gsd_bgnline();
422
423 row = 0;
424 /* floor left */
425 pt[X] = col * (surf->x_mod * surf->xres);
426 pt[Y] =
427 ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
428 pt[Z] = bot;
430
431 /* find nearest row with defined z coordinate */
432 offset = (row * surf->y_mod * surf->cols) + (col * surf->x_mod);
433 col_shift = 0;
434 while (!GET_MAPATT(buff, offset, pt[Z]) && col_shift < max_col_shift) {
435 col_shift++;
436 if (side)
437 offset = (row * surf->y_mod * surf->cols) +
438 ((col - col_shift) * surf->x_mod);
439 else
440 offset = (row * surf->y_mod * surf->cols) +
441 ((col + col_shift) * surf->x_mod);
442 }
443 pt[Z] = pt[Z] * surf->z_exag;
445
446 for (row = 0; row < ycnt - 1; row++) {
447 /* bottom right */
448 pt[X] = col * (surf->x_mod * surf->xres);
449 pt[Y] = ((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) +
457 ((col - col_shift) * surf->x_mod);
458 else
459 offset = (row * surf->y_mod * surf->cols) +
460 ((col + col_shift) * surf->x_mod);
461 }
462 pt[Z] = pt[Z] * surf->z_exag;
464 }
465
466 row--;
467 pt[X] = col * (surf->x_mod * surf->xres);
468 pt[Y] =
469 ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
470 pt[Z] = bot;
472
473 row = 0;
474 pt[X] = col * (surf->x_mod * surf->xres);
475 pt[Y] =
476 ((surf->rows - 1) * surf->yres) - (row * (surf->y_mod * surf->yres));
477 pt[Z] = bot;
479
480 gsd_endline();
481
482 GS_done_draw();
484 gsd_flush();
485
486 return;
487}
488
489/*!
490 \brief ADD
491
492 \param bot
493 \param surf surface (geosurf)
494 \param row
495 \param side
496 */
497void gsd_fringe_horiz_line2(float bot, geosurf *surf, int row, int side)
498{
499 int col;
500 float pt[4];
501 typbuff *buff;
502 long offset;
503 int xcnt;
504
507 gsd_do_scale(1);
508 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
509
510 buff = gs_get_att_typbuff(surf, ATT_TOPO, 0);
511 xcnt = VCOLS(surf);
512 gsd_bgnline();
513
514 col = 0;
515 /* floor left */
516 pt[X] = surf->xmin + (col * (surf->x_mod * surf->xres));
517 pt[Y] = surf->ymax - ((row + side) * (surf->y_mod * surf->yres));
518 pt[Z] = bot;
520
521 offset = 0;
522 GET_MAPATT(buff, offset, pt[Z]);
523 pt[Z] = pt[Z] * surf->z_exag;
525
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 = (long)col * surf->x_mod;
531 GET_MAPATT(buff, offset, pt[Z]);
532 pt[Z] = pt[Z] * surf->z_exag;
534 }
535
536 col--;
537 pt[X] = surf->xmin + (col * (surf->x_mod * surf->xres));
538 pt[Y] = surf->ymax - ((row + side) * (surf->y_mod * surf->yres));
539 pt[Z] = bot;
541
542 gsd_endline();
543
544 GS_done_draw();
546 gsd_flush();
547
548 return;
549}
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition gsd_prim.c:507
void GS_set_draw(int)
Sets which buffer to draw to.
Definition gs2.c:2458
void gsd_do_scale(int)
Set current scale.
Definition gsd_views.c:351
void gsd_bgnqstrip(void)
ADD.
Definition gsd_prim.c:273
void gsd_endqstrip(void)
ADD.
Definition gsd_prim.c:283
void gsd_color_func(unsigned int)
Set current color.
Definition gsd_prim.c:694
void gsd_translate(float, float, float)
Multiply the current matrix by a translation matrix.
Definition gsd_prim.c:535
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition gsd_prim.c:497
void gsd_flush(void)
Mostly for flushing drawing commands across a network.
Definition gsd_prim.c:80
void gsd_zwritemask(unsigned long)
Write out z-mask.
Definition gsd_prim.c:237
void gsd_linewidth(short)
Set width of rasterized lines.
Definition gsd_prim.c:263
void gsd_endline(void)
End line.
Definition gsd_prim.c:403
void gsd_colormode(int)
Set color mode.
Definition gsd_prim.c:94
typbuff * gs_get_att_typbuff(geosurf *, int, int)
Get attribute data buffer.
Definition gs.c:677
void gsd_bgnline(void)
Begin line.
Definition gsd_prim.c:393
void GS_done_draw(void)
Draw done, swap buffers.
Definition gs2.c:2497
void gsd_vert_func(float *)
ADD.
Definition gsd_prim.c:682
float Nbottom[]
Definition gsd_fringe.c:33
void gsd_fringe_vert_poly(float bot, geosurf *surf, int col, int side)
Draw fringe outline in y direction.
Definition gsd_fringe.c:318
#define FRINGE_WIDTH
Definition gsd_fringe.c:23
#define FRINGE_FORE
Definition gsd_fringe.c:22
float Nnorth[]
Normals.
Definition gsd_fringe.c:28
float Nsouth[]
Definition gsd_fringe.c:29
void gsd_fringe_horiz_poly(float bot, geosurf *surf, int row, int side)
Draw fringe polygon in x direction.
Definition gsd_fringe.c:137
float Ntop[]
Definition gsd_fringe.c:32
void gsd_display_fringe(geosurf *surf, unsigned long clr, float elev, int where[4])
Display fridge.
Definition gsd_fringe.c:47
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:223
float Nwest[]
Definition gsd_fringe.c:31
void gsd_fringe_horiz_line2(float bot, geosurf *surf, int row, int side)
ADD.
Definition gsd_fringe.c:497
float Neast[]
Definition gsd_fringe.c:30
#define GET_MAPATT(buff, offset, att)
Definition gsget.h:29
OGSF header file (structures)
#define X
Definition ogsf.h:141
#define ATT_TOPO
Definition ogsf.h:76
#define Z
Definition ogsf.h:143
#define GSD_FRONT
Definition ogsf.h:105
#define Y
Definition ogsf.h:142
#define CM_COLOR
Definition ogsf.h:149
#define VCOLS(gs)
Definition rowcol.h:14
#define VROWS(gs)
Definition rowcol.h:13
Definition ogsf.h:267