123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- /*!
- \file lib/nviz/draw.c
- \brief Nviz library -- Draw map objects to GLX context
- Based on visualization/nviz/src/draw.c and
- visualization/nviz/src/togl_flythrough.c
-
- (C) 2008, 2010-2011 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- \author Updated/modified by Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
- \author Textures by Anna Kratochvilova
- */
- #include <grass/nviz.h>
- #ifndef GL_CLAMP_TO_EDGE
- #define GL_CLAMP_TO_EDGE 0x812F
- #endif
- static int sort_surfs_max(int *, int *, int *, int);
- /*!
- \brief Draw all loaded surfaces
- \param dc nviz data
- \return 1
- */
- int Nviz_draw_all_surf(nv_data * dc)
- {
- int i, nsurfs;
- int sortSurfs[MAX_SURFS], sorti[MAX_SURFS];
- int *surf_list;
- float x, y, z;
- int num, w;
- /* Get position for Light 1 */
- num = 1;
- x = dc->light[num].x;
- y = dc->light[num].y;
- z = dc->light[num].z;
- w = dc->light[num].z;
- surf_list = GS_get_surf_list(&nsurfs);
- sort_surfs_max(surf_list, sortSurfs, sorti, nsurfs);
- G_free(surf_list);
- /* re-initialize lights */
- GS_setlight_position(num, x, y, z, w);
- num = 2;
- GS_setlight_position(num, 0., 0., 1., 0);
- for (i = 0; i < nsurfs; i++) {
- GS_draw_surf(sortSurfs[i]);
- }
- /* GS_draw_cplane_fence params will change - surfs aren't used anymore */
- for (i = 0; i < MAX_CPLANES; i++) {
- if (dc->cp_on[i])
- GS_draw_cplane_fence(sortSurfs[0], sortSurfs[1], i);
- }
- return 1;
- }
- /*!
- \brief Sorts surfaces by max elevation, lowest to highest.
- Puts ordered id numbers in id_sort, leaving id_orig unchanged.
- Puts ordered indices of surfaces from id_orig in indices.
- \param surf pointer to surface array
- \param id_sort
- \param indices
- \param num
- \return 1
- */
- int sort_surfs_max(int *surf, int *id_sort, int *indices, int num)
- {
- int i, j;
- float maxvals[MAX_SURFS];
- float tmp, max = 0., tmin, tmax, tmid;
- for (i = 0; i < num; i++) {
- GS_get_zextents(surf[i], &tmin, &tmax, &tmid);
- if (i == 0)
- max = tmax;
- else
- max = max < tmax ? tmax : max;
- maxvals[i] = tmax;
- }
- for (i = 0; i < num; i++) {
- tmp = maxvals[0];
- indices[i] = 0;
- for (j = 0; j < num; j++) {
- if (maxvals[j] < tmp) {
- tmp = maxvals[j];
- indices[i] = j;
- }
- }
- maxvals[indices[i]] = max + 1;
- id_sort[i] = surf[indices[i]];
- }
- return 1;
- }
- /*!
- \brief Draw all loaded vector sets (lines)
- \return 1
- */
- int Nviz_draw_all_vect()
- {
- /* GS_set_cancel(0); */
- /* in case transparency is set */
- GS_set_draw(GSD_BOTH);
- GS_ready_draw();
- GV_alldraw_vect();
- GS_done_draw();
- GS_set_draw(GSD_BACK);
- /* GS_set_cancel(0); */
- return 1;
- }
- /*!
- \brief Draw all loaded vector point sets
- \return 1
- */
- int Nviz_draw_all_site()
- {
- int i;
- int *site_list, nsites;
- site_list = GP_get_site_list(&nsites);
- /* in case transparency is set */
- GS_set_draw(GSD_BOTH);
- GS_ready_draw();
- for (i = 0; i < nsites; i++) {
- GP_draw_site(site_list[i]);
- }
- G_free(site_list);
- GS_done_draw();
- GS_set_draw(GSD_BACK);
- return 1;
- }
- /*!
- \brief Draw all loaded volume sets
- \return 1
- */
- int Nviz_draw_all_vol()
- {
- int *vol_list, nvols, i;
- vol_list = GVL_get_vol_list(&nvols);
- /* in case transparency is set */
- GS_set_draw(GSD_BOTH);
- GS_ready_draw();
- for (i = 0; i < nvols; i++) {
- GVL_draw_vol(vol_list[i]);
- }
- G_free(vol_list);
- GS_done_draw();
- GS_set_draw(GSD_BACK);
- return 1;
- }
- /*!
- \brief Draw all map objects (in full resolution) and decorations
- \param data nviz data
- */
- int Nviz_draw_all(nv_data * data)
- {
- int i;
- int draw_surf, draw_vect, draw_site, draw_vol;
-
- draw_surf = 1;
- draw_vect = 1;
- draw_site = 1;
- draw_vol = 1;
- /*
- draw_north_arrow = 0;
- arrow_x = 0;
- draw_label = 0;
- draw_legend = 0;
- draw_fringe = 0;
- draw_scalebar = 0;
- draw_bar_x = 0;
- */
-
- GS_set_draw(GSD_BACK); /* needs to be BACK to avoid flickering */
- GS_ready_draw();
- GS_clear(data->bgcolor);
- if (draw_surf)
- Nviz_draw_all_surf(data);
- if (draw_vect)
- Nviz_draw_all_vect(data);
- if (draw_site)
- Nviz_draw_all_site(data);
- if (draw_vol)
- Nviz_draw_all_vol(data);
-
- for(i = 0; i < data->num_fringes; i++) {
- struct fringe_data * f = data->fringe[i];
- GS_draw_fringe(f->id, f->color, f->elev, f->where);
- }
- /* North Arrow */
- if (data->draw_arrow) {
- gsd_north_arrow(data->arrow->where, data->arrow->size,
- 0, data->arrow->color, data->arrow->color);
- }
- /* scale bar */
- for (i = 0; i < data->num_scalebars; i++) {
- if (data->scalebar[i]){
- struct scalebar_data *s = data->scalebar[i];
- gsd_scalebar_v2(s->where, s->size, 0, s->color, s->color);
- }
- }
- GS_done_draw();
- GS_set_draw(GSD_BACK);
- return 1;
- }
- /*!
- \brief Draw all surfaces in wireframe (quick mode)
- Draw modes:
- - DRAW_QUICK_SURFACE
- - DRAW_QUICK_VLINES
- - DRAW_QUICK_VPOINTS
- - DRAW_QUICK_VOLUME
- \param data nviz data
- \param draw_mode draw mode
-
- \return 1
- */
- int Nviz_draw_quick(nv_data * data, int draw_mode)
- {
- GS_set_draw(GSD_BACK);
-
- GS_ready_draw();
-
- GS_clear(data->bgcolor);
-
- /* draw surfaces */
- if (draw_mode & DRAW_QUICK_SURFACE)
- GS_alldraw_wire();
-
- /* draw vector lines */
- if (draw_mode & DRAW_QUICK_VLINES)
- GV_alldraw_vect();
-
- /* draw vector points */
- if (draw_mode & DRAW_QUICK_VPOINTS)
- GP_alldraw_site();
-
- /* draw volumes */
- if (draw_mode & DRAW_QUICK_VOLUME) {
- GVL_alldraw_wire();
- }
-
- GS_done_draw();
-
- return 1;
- }
- /*!
- \brief Load image into texture
- \param image_data image data
- \param width, height image screen size
- \param alpha has alpha channel
- */
- int Nviz_load_image(GLubyte *image_data, int width, int height, int alpha)
- {
- unsigned int texture_id;
- int in_format;
- GLenum format;
- if (alpha)
- {
- in_format = 4;
- format = GL_RGBA;
- }
- else
- {
- in_format = 3;
- format = GL_RGB;
- }
- glGenTextures( 1, &texture_id);
- glBindTexture(GL_TEXTURE_2D, texture_id);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexImage2D(GL_TEXTURE_2D, 0, in_format, width, height, 0,format,
- GL_UNSIGNED_BYTE, image_data);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- return texture_id;
- }
- /*!
- \brief Set ortho view for drawing images
- \param width, height image screen size
- */
- void Nviz_set_2D(int width, int height)
- {
- glEnable(GL_BLEND); /* images are transparent */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, width, 0, height, -1, 1);
-
- /* set coordinate system from upper left corner */
- glScalef(1, -1, 1);
- glTranslatef(0, -height, 0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
- /*!
- \brief Draw image as texture
- \param x, y image coordinates
- \param width, height image size
- \param texture_id texture id
- */
- void Nviz_draw_image(int x, int y, int width, int height, int texture_id)
- {
- glBindTexture(GL_TEXTURE_2D, texture_id);
- GS_set_draw(GSD_FRONT);
- glEnable(GL_TEXTURE_2D);
- glBegin(GL_QUADS);
- glTexCoord2d(0.0,1.0);
- glVertex2d(x, y);
- glTexCoord2d(0.0,0.0);
- glVertex2d(x, y + height);
- glTexCoord2d(1.0,0.0);
- glVertex2d(x + width, y + height);
- glTexCoord2d(1.0,1.0);
- glVertex2d(x + width, y);
- glEnd();
- GS_done_draw();
- glDisable(GL_TEXTURE_2D);
- }
- /*!
- \brief Delete texture
- \param texture_id texture id
- */
- void Nviz_del_texture(int texture_id)
- {
- GLuint t[1];
- t[0] = texture_id;
- glDeleteTextures(1, t);
- }
- /*!
- \brief Get maximum texture size
- */
- void Nviz_get_max_texture(int *size)
- {
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, size);
- }
|