GRASS GIS 8 Programmer's Manual 8.2.0(2022)-exported
nviz/draw.c
Go to the documentation of this file.
1/*!
2 \file lib/nviz/draw.c
3
4 \brief Nviz library -- Draw map objects to GLX context
5
6 Based on visualization/nviz/src/draw.c and
7 visualization/nviz/src/togl_flythrough.c
8
9 (C) 2008, 2010-2011 by the GRASS Development Team
10 This program is free software under the GNU General Public License
11 (>=v2). Read the file COPYING that comes with GRASS for details.
12
13 \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
14 \author Textures by Anna Kratochvilova
15 */
16
17#include <grass/nviz.h>
18
19#ifndef GL_CLAMP_TO_EDGE
20#define GL_CLAMP_TO_EDGE 0x812F
21#endif
22
23static int sort_surfs_max(int *, int *, int *, int);
24
25/*!
26 \brief Draw all loaded surfaces
27
28 \param dc nviz data
29
30 \return 1
31 */
32int Nviz_draw_all_surf(nv_data * dc)
33{
34 int i, nsurfs;
35 int sortSurfs[MAX_SURFS], sorti[MAX_SURFS];
36 int *surf_list;
37 float x, y, z;
38 int num, w;
39
40 /* Get position for Light 1 */
41 num = 1;
42 x = dc->light[num].x;
43 y = dc->light[num].y;
44 z = dc->light[num].z;
45 w = dc->light[num].z;
46
47 surf_list = GS_get_surf_list(&nsurfs);
48
49 sort_surfs_max(surf_list, sortSurfs, sorti, nsurfs);
50
51 G_free(surf_list);
52
53 /* re-initialize lights */
54 GS_setlight_position(num, x, y, z, w);
55 num = 2;
56 GS_setlight_position(num, 0., 0., 1., 0);
57
58 for (i = 0; i < nsurfs; i++) {
59 GS_draw_surf(sortSurfs[i]);
60 }
61
62 /* GS_draw_cplane_fence params will change - surfs aren't used anymore */
63 for (i = 0; i < MAX_CPLANES; i++) {
64 if (dc->cp_on[i])
65 GS_draw_cplane_fence(sortSurfs[0], sortSurfs[1], i);
66 }
67
68 return 1;
69}
70
71/*!
72 \brief Sorts surfaces by max elevation, lowest to highest.
73
74 Puts ordered id numbers in id_sort, leaving id_orig unchanged.
75 Puts ordered indices of surfaces from id_orig in indices.
76
77 \param surf pointer to surface array
78 \param id_sort
79 \param indices
80 \param num
81
82 \return 1
83 */
84int sort_surfs_max(int *surf, int *id_sort, int *indices, int num)
85{
86 int i, j;
87 float maxvals[MAX_SURFS];
88 float tmp, max = 0., tmin, tmax, tmid;
89
90 for (i = 0; i < num; i++) {
91 GS_get_zextents(surf[i], &tmin, &tmax, &tmid);
92 if (i == 0)
93 max = tmax;
94 else
95 max = max < tmax ? tmax : max;
96 maxvals[i] = tmax;
97 }
98
99 for (i = 0; i < num; i++) {
100 tmp = maxvals[0];
101 indices[i] = 0;
102 for (j = 0; j < num; j++) {
103 if (maxvals[j] < tmp) {
104 tmp = maxvals[j];
105 indices[i] = j;
106 }
107 }
108
109 maxvals[indices[i]] = max + 1;
110 id_sort[i] = surf[indices[i]];
111 }
112
113 return 1;
114}
115
116/*!
117 \brief Draw all loaded vector sets (lines)
118
119 \return 1
120 */
122{
123 /* GS_set_cancel(0); */
124
125 /* in case transparency is set */
126 GS_set_draw(GSD_BOTH);
127
129
131
132 GS_done_draw();
133
134 GS_set_draw(GSD_BACK);
135
136 /* GS_set_cancel(0); */
137
138 return 1;
139}
140
141/*!
142 \brief Draw all loaded vector point sets
143
144 \return 1
145 */
147{
148 int i;
149 int *site_list, nsites;
150
151 site_list = GP_get_site_list(&nsites);
152
153 /* in case transparency is set */
154 GS_set_draw(GSD_BOTH);
155
157
158 for (i = 0; i < nsites; i++) {
159 GP_draw_site(site_list[i]);
160 }
161 G_free(site_list);
162
163 GS_done_draw();
164
165 GS_set_draw(GSD_BACK);
166
167 return 1;
168}
169
170/*!
171 \brief Draw all loaded volume sets
172
173 \return 1
174 */
176{
177 int *vol_list, nvols, i;
178
179 vol_list = GVL_get_vol_list(&nvols);
180
181 /* in case transparency is set */
182 GS_set_draw(GSD_BOTH);
183
185
186 for (i = 0; i < nvols; i++) {
187 GVL_draw_vol(vol_list[i]);
188 }
189
190 G_free(vol_list);
191
192 GS_done_draw();
193
194 GS_set_draw(GSD_BACK);
195
196 return 1;
197}
198
199/*!
200 \brief Draw all map objects (in full resolution) and decorations
201
202 \param data nviz data
203 */
204int Nviz_draw_all(nv_data * data)
205{
206 int i;
207 int draw_surf, draw_vect, draw_site, draw_vol;
208
209 draw_surf = 1;
210 draw_vect = 1;
211 draw_site = 1;
212 draw_vol = 1;
213 /*
214 draw_north_arrow = 0;
215 arrow_x = 0;
216 draw_label = 0;
217 draw_legend = 0;
218 draw_fringe = 0;
219 draw_scalebar = 0;
220 draw_bar_x = 0;
221 */
222
223 GS_set_draw(GSD_BACK); /* needs to be BACK to avoid flickering */
224
226
227 GS_clear(data->bgcolor);
228
229 if (draw_surf)
230 Nviz_draw_all_surf(data);
231
232 if (draw_vect)
234
235 if (draw_site)
237
238 if (draw_vol)
240
241 for(i = 0; i < data->num_fringes; i++) {
242 struct fringe_data * f = data->fringe[i];
243 GS_draw_fringe(f->id, f->color, f->elev, f->where);
244 }
245
246 /* North Arrow */
247 if (data->draw_arrow) {
248 gsd_north_arrow(data->arrow->where, data->arrow->size,
249 0, data->arrow->color, data->arrow->color);
250 }
251
252 /* scale bar */
253 for (i = 0; i < data->num_scalebars; i++) {
254 if (data->scalebar[i]){
255 struct scalebar_data *s = data->scalebar[i];
256 gsd_scalebar_v2(s->where, s->size, 0, s->color, s->color);
257 }
258 }
259 GS_done_draw();
260 GS_set_draw(GSD_BACK);
261
262 return 1;
263}
264
265/*!
266 \brief Draw all surfaces in wireframe (quick mode)
267
268 Draw modes:
269 - DRAW_QUICK_SURFACE
270 - DRAW_QUICK_VLINES
271 - DRAW_QUICK_VPOINTS
272 - DRAW_QUICK_VOLUME
273
274 \param data nviz data
275 \param draw_mode draw mode
276
277 \return 1
278 */
279int Nviz_draw_quick(nv_data * data, int draw_mode)
280{
281 GS_set_draw(GSD_BACK);
282
284
285 GS_clear(data->bgcolor);
286
287 /* draw surfaces */
288 if (draw_mode & DRAW_QUICK_SURFACE)
290
291 /* draw vector lines */
292 if (draw_mode & DRAW_QUICK_VLINES)
294
295 /* draw vector points */
296 if (draw_mode & DRAW_QUICK_VPOINTS)
298
299 /* draw volumes */
300 if (draw_mode & DRAW_QUICK_VOLUME) {
302 }
303
304 GS_done_draw();
305
306 return 1;
307}
308
309/*!
310 \brief Load image into texture
311
312 \param image_data image data
313 \param width, height image screen size
314 \param alpha has alpha channel
315*/
316int Nviz_load_image(GLubyte *image_data, int width, int height, int alpha)
317{
318 unsigned int texture_id;
319 int in_format;
320 GLenum format;
321
322 if (alpha)
323 {
324 in_format = 4;
325 format = GL_RGBA;
326 }
327 else
328 {
329 in_format = 3;
330 format = GL_RGB;
331 }
332 glGenTextures( 1, &texture_id);
333 glBindTexture(GL_TEXTURE_2D, texture_id);
334 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
335
336 glTexImage2D(GL_TEXTURE_2D, 0, in_format, width, height, 0,format,
337 GL_UNSIGNED_BYTE, image_data);
338
339 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
340 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
341
342 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
343 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
344
345 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
346
347 return texture_id;
348}
349
350/*!
351 \brief Set ortho view for drawing images
352
353 \param width, height image screen size
354*/
355void Nviz_set_2D(int width, int height)
356{
357 glEnable(GL_BLEND); /* images are transparent */
358 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
359
360 glMatrixMode(GL_PROJECTION);
361 glLoadIdentity();
362 glOrtho(0, width, 0, height, -1, 1);
363
364 /* set coordinate system from upper left corner */
365 glScalef(1, -1, 1);
366 glTranslatef(0, -height, 0);
367
368 glMatrixMode(GL_MODELVIEW);
369 glLoadIdentity();
370}
371
372/*!
373 \brief Draw image as texture
374
375 \param x, y image coordinates
376 \param width, height image size
377 \param texture_id texture id
378*/
379void Nviz_draw_image(int x, int y, int width, int height, int texture_id)
380{
381 glBindTexture(GL_TEXTURE_2D, texture_id);
382 GS_set_draw(GSD_FRONT);
383
384 glEnable(GL_TEXTURE_2D);
385
386 glBegin(GL_QUADS);
387
388 glTexCoord2d(0.0,1.0);
389 glVertex2d(x, y);
390 glTexCoord2d(0.0,0.0);
391 glVertex2d(x, y + height);
392 glTexCoord2d(1.0,0.0);
393 glVertex2d(x + width, y + height);
394 glTexCoord2d(1.0,1.0);
395 glVertex2d(x + width, y);
396
397 glEnd();
398
399 GS_done_draw();
400 glDisable(GL_TEXTURE_2D);
401}
402
403/*!
404 \brief Delete texture
405
406 \param texture_id texture id
407*/
408void Nviz_del_texture(int texture_id)
409{
410 GLuint t[1];
411
412 t[0] = texture_id;
413 glDeleteTextures(1, t);
414}
415
416/*!
417 \brief Get maximum texture size
418
419*/
420void Nviz_get_max_texture(int *size)
421{
422 glGetIntegerv(GL_MAX_TEXTURE_SIZE, size);
423}
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
double t
int * GP_get_site_list(int *numsites)
Get list of point sets.
Definition: gp2.c:101
void GP_draw_site(int id)
Draw point set.
Definition: gp2.c:573
void GP_alldraw_site(void)
Draw all available point sets.
Definition: gp2.c:607
int GS_get_zextents(int id, float *min, float *max, float *mid)
Get z-extent for a single surface.
Definition: gs2.c:2666
void GS_draw_surf(int id)
Draw surface.
Definition: gs2.c:1864
void GS_alldraw_wire(void)
Draw all wires.
Definition: gs2.c:1919
void GS_clear(int col)
Clear view.
Definition: gs2.c:3418
int * GS_get_surf_list(int *numsurfs)
Get surface list.
Definition: gs2.c:1539
void GS_draw_fringe(int id, unsigned long clr, float elev, int *where)
Draw fringe around data (surface) at selected corners.
Definition: gs2.c:823
void GS_ready_draw(void)
Definition: gs2.c:2488
int GS_draw_cplane_fence(int hs1, int hs2, int num)
Draw cplace fence ?
Definition: gs2.c:3175
void GS_setlight_position(int num, float xpos, float ypos, float zpos, int local)
Set light position.
Definition: gs2.c:309
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
int gsd_north_arrow(float *pos2, float len, GLuint fontbase, unsigned long arw_clr, unsigned long text_clr)
Draw North Arrow takes OpenGL coords and size.
Definition: gsd_objs.c:827
int gsd_scalebar_v2(float *pos, float len, GLuint fontbase, unsigned long bar_clr, unsigned long text_clr)
Draw Scalebar (as lines)
Definition: gsd_objs.c:1249
void GV_alldraw_vect(void)
Draw all loaded vector sets.
Definition: gv2.c:506
void GVL_alldraw_wire(void)
Draw all volume sets in wire mode.
Definition: gvl2.c:455
int * GVL_get_vol_list(int *numvols)
Get list of loaded volume sets.
Definition: gvl2.c:181
void GVL_draw_vol(int vid)
Draw volume set.
Definition: gvl2.c:402
int Nviz_load_image(GLubyte *image_data, int width, int height, int alpha)
Load image into texture.
Definition: nviz/draw.c:316
void Nviz_get_max_texture(int *size)
Get maximum texture size.
Definition: nviz/draw.c:420
int Nviz_draw_all_vect(void)
Draw all loaded vector sets (lines)
Definition: nviz/draw.c:121
void Nviz_draw_image(int x, int y, int width, int height, int texture_id)
Draw image as texture.
Definition: nviz/draw.c:379
int Nviz_draw_all_surf(nv_data *dc)
Draw all loaded surfaces.
Definition: nviz/draw.c:32
void Nviz_set_2D(int width, int height)
Set ortho view for drawing images.
Definition: nviz/draw.c:355
int Nviz_draw_quick(nv_data *data, int draw_mode)
Draw all surfaces in wireframe (quick mode)
Definition: nviz/draw.c:279
int Nviz_draw_all(nv_data *data)
Draw all map objects (in full resolution) and decorations.
Definition: nviz/draw.c:204
void Nviz_del_texture(int texture_id)
Delete texture.
Definition: nviz/draw.c:408
int Nviz_draw_all_vol(void)
Draw all loaded volume sets.
Definition: nviz/draw.c:175
#define GL_CLAMP_TO_EDGE
Definition: nviz/draw.c:20
int Nviz_draw_all_site(void)
Draw all loaded vector point sets.
Definition: nviz/draw.c:146
#define max(a, b)
#define x