GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
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 (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
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
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] = ((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
211
212 GS_done_draw();
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 */
227void 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
238 GS_set_draw(GSD_FRONT);
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();
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 */
322void 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
334 GS_set_draw(GSD_FRONT);
336 gsd_do_scale(1);
337 gsd_translate(surf->x_trans, surf->y_trans, surf->z_trans);
338
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
391
392 GS_done_draw();
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 */
407void 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
418 GS_set_draw(GSD_FRONT);
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();
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 */
501void 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
509 GS_set_draw(GSD_FRONT);
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();
550 gsd_flush();
551
552 return;
553}
void GS_set_draw(int where)
Sets which buffer to draw to.
Definition gs2.c:2459
void GS_done_draw(void)
Draw done, swap buffers.
Definition gs2.c:2498
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: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
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition gsd_prim.c:511
void gsd_zwritemask(unsigned long n)
Write out z-mask.
Definition gsd_prim.c:241
void gsd_vert_func(float *pt)
ADD.
Definition gsd_prim.c:686
void gsd_bgnqstrip(void)
ADD.
Definition gsd_prim.c:277
void gsd_colormode(int cm)
Set color mode.
Definition gsd_prim.c:98
void gsd_endqstrip(void)
ADD.
Definition gsd_prim.c:287
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_endline(void)
End line.
Definition gsd_prim.c:407
void gsd_bgnline(void)
Begin line.
Definition gsd_prim.c:397
void gsd_translate(float dx, float dy, float dz)
Multiply the current matrix by a translation matrix.
Definition gsd_prim.c:539
void gsd_color_func(unsigned int col)
Set current color.
Definition gsd_prim.c:698
void gsd_linewidth(short n)
Set width of rasterized lines.
Definition gsd_prim.c:267
void gsd_do_scale(int doexag)
Set current scale.
Definition gsd_views.c:355
#define GET_MAPATT(buff, offset, att)
Definition gsget.h:29
#define VCOLS(gs)
Definition rowcol.h:14
#define VROWS(gs)
Definition rowcol.h:13
#define X(j)
#define Y(j)