GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
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 
23 static 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  */
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  */
84 int 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 */
127 
128  GS_ready_draw();
129 
130  GV_alldraw_vect();
131 
132  GS_done_draw();
133 
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 */
155 
156  GS_ready_draw();
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 
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 */
183 
184  GS_ready_draw();
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 
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  */
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 
225  GS_ready_draw();
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();
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  */
279 int Nviz_draw_quick(nv_data * data, int draw_mode)
280 {
282 
283  GS_ready_draw();
284 
285  GS_clear(data->bgcolor);
286 
287  /* draw surfaces */
288  if (draw_mode & DRAW_QUICK_SURFACE)
289  GS_alldraw_wire();
290 
291  /* draw vector lines */
292  if (draw_mode & DRAW_QUICK_VLINES)
293  GV_alldraw_vect();
294 
295  /* draw vector points */
296  if (draw_mode & DRAW_QUICK_VPOINTS)
297  GP_alldraw_site();
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 */
316 int 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 */
355 void 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 */
379 void Nviz_draw_image(int x, int y, int width, int height, int texture_id)
380 {
381  glBindTexture(GL_TEXTURE_2D, texture_id);
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 */
408 void 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 */
421 {
422  glGetIntegerv(GL_MAX_TEXTURE_SIZE, size);
423 }
#define DRAW_QUICK_VLINES
Definition: nviz.h:54
float size
Definition: nviz.h:97
#define MAX_CPLANES
Definition: ogsf.h:45
struct fringe_data ** fringe
Definition: nviz.h:117
void Nviz_set_2D(int width, int height)
Set ortho view for drawing images.
Definition: nviz/draw.c:355
int Nviz_draw_all_vect(void)
Draw all loaded vector sets (lines)
Definition: nviz/draw.c:121
void GS_draw_surf(int)
Draw surface.
Definition: gs2.c:1864
int * GP_get_site_list(int *)
Get list of point sets.
Definition: gp2.c:101
void GS_ready_draw(void)
Definition: gs2.c:2488
int Nviz_draw_all(nv_data *data)
Draw all map objects (in full resolution) and decorations.
Definition: nviz/draw.c:204
void GVL_draw_vol(int)
Draw volume set.
Definition: gvl2.c:402
float z
Definition: nviz.h:75
void GVL_alldraw_wire(void)
Draw all volume sets in wire mode.
Definition: gvl2.c:455
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
int id
Definition: nviz.h:80
float size
Definition: nviz.h:89
unsigned long color
Definition: nviz.h:96
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 draw_arrow
Definition: nviz.h:120
#define GSD_BOTH
Definition: ogsf.h:103
#define x
#define max(x, y)
Definition: draw2.c:32
#define MAX_SURFS
Definition: ogsf.h:38
void GS_clear(int)
Clear view.
Definition: gs2.c:3418
void GS_alldraw_wire(void)
Draw all wires.
Definition: gs2.c:1919
int GS_get_zextents(int, float *, float *, float *)
Get z-extent for a single surface.
Definition: gs2.c:2666
#define DRAW_QUICK_VPOINTS
Definition: nviz.h:55
double t
Definition: r_raster.c:39
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
float elev
Definition: nviz.h:82
unsigned long color
Definition: nviz.h:81
void GP_alldraw_site(void)
Draw all available point sets.
Definition: gp2.c:607
#define DRAW_QUICK_VOLUME
Definition: nviz.h:56
float x
Definition: nviz.h:75
int * GS_get_surf_list(int *)
Get surface list.
Definition: gs2.c:1539
float y
Definition: nviz.h:75
void GS_done_draw(void)
Draw done, swap buffers.
Definition: gs2.c:2501
int GS_draw_cplane_fence(int, int, int)
Draw cplace fence ?
Definition: gs2.c:3175
struct arrow_data * arrow
Definition: nviz.h:121
void GS_draw_fringe(int, unsigned long, float, int *)
Draw fringe around data (surface) at selected corners.
Definition: gs2.c:823
void GS_setlight_position(int, float, float, float, int)
Set light position.
Definition: gs2.c:309
int cp_on[MAX_CPLANES]
Definition: nviz.h:108
light_data light[MAX_LIGHTS]
Definition: nviz.h:113
int num_scalebars
Definition: nviz.h:124
#define GSD_BACK
Definition: ogsf.h:102
float where[3]
Definition: nviz.h:98
int num_fringes
Definition: nviz.h:116
int Nviz_draw_all_surf(nv_data *dc)
Draw all loaded surfaces.
Definition: nviz/draw.c:32
Definition: nviz.h:101
int Nviz_draw_quick(nv_data *data, int draw_mode)
Draw all surfaces in wireframe (quick mode)
Definition: nviz/draw.c:279
#define GSD_FRONT
Definition: ogsf.h:101
int where[4]
Definition: nviz.h:83
#define GL_CLAMP_TO_EDGE
Definition: nviz/draw.c:20
void Nviz_get_max_texture(int *size)
Get maximum texture size.
Definition: nviz/draw.c:420
int gsd_scalebar_v2(float *, float, GLuint, unsigned long, unsigned long)
Draw Scalebar (as lines)
Definition: gsd_objs.c:1249
void GP_draw_site(int)
Draw point set.
Definition: gp2.c:573
#define DRAW_QUICK_SURFACE
Definition: nviz.h:53
struct scalebar_data ** scalebar
Definition: nviz.h:125
int Nviz_load_image(GLubyte *image_data, int width, int height, int alpha)
Load image into texture.
Definition: nviz/draw.c:316
void GS_set_draw(int)
Sets which buffer to draw to.
Definition: gs2.c:2462
float where[3]
Definition: nviz.h:90
int bgcolor
Definition: nviz.h:128
int gsd_north_arrow(float *, float, GLuint, unsigned long, unsigned long)
Draw North Arrow takes OpenGL coords and size.
Definition: gsd_objs.c:827
int * GVL_get_vol_list(int *)
Get list of loaded volume sets.
Definition: gvl2.c:181
unsigned long color
Definition: nviz.h:88
int Nviz_draw_all_site(void)
Draw all loaded vector point sets.
Definition: nviz/draw.c:146
void GV_alldraw_vect(void)
Draw all loaded vector sets.
Definition: gv2.c:506