GRASS Programmer's Manual  6.4.2(2012)
GS2.c
Go to the documentation of this file.
00001 
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <math.h>
00034 
00035 #include <grass/config.h>
00036 
00037 #if defined(OPENGL_X11) || defined(OPENGL_WINDOWS)
00038 #include <GL/gl.h>
00039 #include <GL/glu.h>
00040 #elif defined(OPENGL_AQUA)
00041 #include <OpenGL/gl.h>
00042 #include <OpenGL/glu.h>
00043 #endif
00044 
00045 #include <grass/gis.h>
00046 #include <grass/gstypes.h>
00047 #include <grass/glocale.h>
00048 
00049 #include "gsget.h"
00050 #include "rowcol.h"
00051 #include "rgbpack.h"
00052 
00053 /* Hack to make NVIZ2.2 query functions.("What's Here" and "Look at")
00054  * to work.
00055  * Uses gs_los_intersect1() instead of gs_los_intersect().
00056  * Pierre de Mouveaux - 31 oct. 1999. p_de_mouveaux@hotmail.com.
00057  */
00058 #define NVIZ_HACK 1
00059 
00060 int gsd_getViewport(GLint *, GLint *);
00061 
00062 /* array of surface ids */
00063 static int Surf_ID[MAX_SURFS];
00064 static int Next_surf = 0;
00065 static int SDref_surf = 0;
00066 
00067 /* attributes array */
00068 static float Default_const[MAX_ATTS];
00069 static float Default_nulls[MAX_ATTS];
00070 
00071 /* largest dimension */
00072 static float Longdim;
00073 
00074 /* N, S, W, E */
00075 static float Region[4];
00076 static geoview Gv;
00077 static geodisplay Gd;
00078 static struct Cell_head wind;
00079 static int Buffermode;
00080 static int Numlights = 0;
00081 static int Modelshowing = 0;
00082 
00083 void void_func(void)
00084 {
00085     return;
00086 }
00087 
00095 void GS_libinit(void)
00096 {
00097     static int first = 1;
00098 
00099     G_get_set_window(&wind);
00100 
00101     Region[0] = wind.north;
00102     Region[1] = wind.south;
00103     Region[2] = wind.west;
00104     Region[3] = wind.east;
00105 
00106     /* scale largest dimension to GS_UNIT_SIZE */
00107     if ((wind.east - wind.west) > (wind.north - wind.south)) {
00108         Longdim = (wind.east - wind.west);
00109     }
00110     else {
00111         Longdim = (wind.north - wind.south);
00112     }
00113 
00114     Gv.scale = GS_UNIT_SIZE / Longdim;
00115 
00116     Cxl_func = void_func;
00117     Swap_func = void_func;
00118 
00119     if (first) {
00120         gs_init();
00121     }
00122 
00123     first = 0;
00124 
00125     return;
00126 }
00127 
00135 int GS_get_longdim(float *dim)
00136 {
00137     *dim = Longdim;
00138 
00139     G_debug(3, "GS_get_longdim(): dim=%g", *dim);
00140 
00141     return (1);
00142 }
00143 
00151 int GS_get_region(float *n, float *s, float *w, float *e)
00152 {
00153     *n = Region[0];
00154     *s = Region[1];
00155     *w = Region[2];
00156     *e = Region[3];
00157 
00158     return (1);
00159 }
00160 
00167 void GS_set_att_defaults(float *defs, float *null_defs)
00168 {
00169     int i;
00170 
00171     G_debug(3, "GS_set_att_defaults");
00172 
00173     for (i = 0; i < MAX_ATTS; i++) {
00174         Default_const[i] = defs[i];
00175         Default_nulls[i] = null_defs[i];
00176     }
00177 
00178     return;
00179 }
00180 
00189 int GS_surf_exists(int id)
00190 {
00191     int i, found = 0;
00192 
00193     G_debug(3, "GS_surf_exists(): id=%d", id);
00194 
00195 
00196     if (NULL == gs_get_surf(id)) {
00197         return (0);
00198     }
00199 
00200     for (i = 0; i < Next_surf && !found; i++) {
00201         if (Surf_ID[i] == id) {
00202             found = 1;
00203         }
00204     }
00205 
00206     return (found);
00207 }
00208 
00219 int GS_new_surface(void)
00220 {
00221     geosurf *ns;
00222 
00223     G_debug(3, "GS_new_surface():");
00224 
00225     if (Next_surf < MAX_SURFS) {
00226         ns = gs_get_new_surface();
00227         gs_init_surf(ns, wind.west + wind.ew_res / 2.,
00228                      wind.south + wind.ns_res / 2., wind.rows, wind.cols,
00229                      wind.ew_res, wind.ns_res);
00230         gs_set_defaults(ns, Default_const, Default_nulls);
00231 
00232         /* make default shine current */
00233         gs_set_att_src(ns, ATT_SHINE, CONST_ATT);
00234 
00235         Surf_ID[Next_surf] = ns->gsurf_id;
00236         ++Next_surf;
00237 
00238         G_debug(3, "    id=%d", ns->gsurf_id);
00239 
00240         return (ns->gsurf_id);
00241     }
00242 
00243 
00244 
00245     return (-1);
00246 }
00247 
00254 int GS_new_light(void)
00255 {
00256     static int first = 1;
00257     int i;
00258 
00259     if (first) {
00260         first = 0;
00261 
00262         for (i = 0; i < MAX_LIGHTS; i++) {
00263             Gv.lights[i].position[X] = Gv.lights[i].position[Y] = 0.0;
00264             Gv.lights[i].position[Z] = 1.0;
00265             Gv.lights[i].position[W] = 0.0;     /* infinite */
00266             Gv.lights[i].color[0] = Gv.lights[i].color[1] =
00267                 Gv.lights[i].color[2] = 1.0;
00268             Gv.lights[i].ambient[0] = Gv.lights[i].ambient[1] =
00269                 Gv.lights[i].ambient[2] = 0.2;
00270             Gv.lights[i].shine = 32.0;
00271         }
00272 
00273         gsd_init_lightmodel();
00274     }
00275 
00276     if (Numlights < MAX_LIGHTS) {
00277         gsd_deflight(Numlights + 1, &(Gv.lights[Numlights]));
00278         gsd_switchlight(Numlights + 1, 1);
00279 
00280         return (++Numlights);
00281     }
00282 
00283     return (-1);
00284 }
00285 
00295 void GS_setlight_position(int num, float xpos, float ypos, float zpos,
00296                           int local)
00297 {
00298     if (num) {
00299         num -= 1;
00300         if (num < Numlights) {
00301             Gv.lights[num].position[X] = xpos;
00302             Gv.lights[num].position[Y] = ypos;
00303             Gv.lights[num].position[Z] = zpos;
00304             Gv.lights[num].position[W] = (float)local;
00305 
00306             gsd_deflight(num + 1, &(Gv.lights[num]));
00307         }
00308     }
00309 
00310     return;
00311 }
00312 
00313 
00321 void GS_getlight_position(int num, float *xpos, float *ypos, float *zpos,
00322                           int *local)
00323 {
00324     if (num) {
00325         num -= 1;
00326         if (num < Numlights) {
00327             *xpos = Gv.lights[num].position[X];
00328             *ypos = Gv.lights[num].position[Y];
00329             *zpos = Gv.lights[num].position[Z];
00330             *local = (int)Gv.lights[num].position[W];
00331 
00332         }
00333     }
00334 
00335     return;
00336 }
00337 
00344 void GS_setlight_color(int num, float red, float green, float blue)
00345 {
00346     if (num) {
00347         num -= 1;
00348         if (num < Numlights) {
00349             Gv.lights[num].color[0] = red;
00350             Gv.lights[num].color[1] = green;
00351             Gv.lights[num].color[2] = blue;
00352 
00353             gsd_deflight(num + 1, &(Gv.lights[num]));
00354         }
00355     }
00356 
00357     return;
00358 }
00359 
00366 void GS_getlight_color(int num, float *red, float *green, float *blue)
00367 {
00368     if (num) {
00369         num -= 1;
00370         if (num < Numlights) {
00371             *red = Gv.lights[num].color[0];
00372             *green = Gv.lights[num].color[1];
00373             *blue = Gv.lights[num].color[2];
00374         }
00375     }
00376 
00377     return;
00378 }
00379 
00388 void GS_setlight_ambient(int num, float red, float green, float blue)
00389 {
00390     if (num) {
00391         num -= 1;
00392         if (num < Numlights) {
00393             Gv.lights[num].ambient[0] = red;
00394             Gv.lights[num].ambient[1] = green;
00395             Gv.lights[num].ambient[2] = blue;
00396 
00397             gsd_deflight(num + 1, &(Gv.lights[num]));
00398         }
00399     }
00400 
00401     return;
00402 }
00403 
00410 void GS_getlight_ambient(int num, float *red, float *green, float *blue)
00411 {
00412     if (num) {
00413         num -= 1;
00414         if (num < Numlights) {
00415             *red = Gv.lights[num].ambient[0];
00416             *green = Gv.lights[num].ambient[1];
00417             *blue = Gv.lights[num].ambient[2];
00418         }
00419     }
00420 
00421     return;
00422 }
00423 
00424 
00428 void GS_lights_off(void)
00429 {
00430     int i;
00431 
00432     for (i = 0; i < Numlights; i++) {
00433         gsd_switchlight(i + 1, 0);
00434     }
00435 
00436     return;
00437 }
00438 
00442 void GS_lights_on(void)
00443 {
00444     int i;
00445 
00446     for (i = 0; i < Numlights; i++) {
00447         gsd_switchlight(i + 1, 1);
00448     }
00449 
00450     return;
00451 }
00452 
00459 void GS_switchlight(int num, int on)
00460 {
00461     if (num) {
00462         num -= 1;
00463 
00464         if (num < Numlights) {
00465             gsd_switchlight(num + 1, on);
00466         }
00467     }
00468 
00469     return;
00470 }
00471 
00478 int GS_transp_is_set(void)
00479 {
00480     return (gs_att_is_set(NULL, ATT_TRANSP) || (FC_GREY == gsd_getfc()));
00481 }
00482 
00488 void GS_get_modelposition1(float pos[])
00489 {
00490     /* TODO: Still needs work to handle other cases */
00491     /* this is a quick hack to get lighting adjustments debugged */
00492     /*
00493        GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], center);
00494        GS_v3mult(center, 1000);
00495        GS_v3add(center, Gv.from_to[FROM]);
00496      */
00497 
00498     gs_get_datacenter(pos);
00499     gs_get_data_avg_zmax(&(pos[Z]));
00500 
00501     G_debug(1, "GS_get_modelposition1(): model position: %f %f %f",
00502             pos[X], pos[Y], pos[Z]);
00503 
00504     return;
00505 }
00506 
00517 void GS_get_modelposition(float *siz, float *pos)
00518 {
00519     float dist, near_h, dir[3];
00520 
00521     dist = 2. * Gd.nearclip;
00522 
00523     near_h = 2.0 * tan(4.0 * atan(1.) * Gv.fov / 3600.) * dist;
00524     *siz = near_h / 8.0;
00525 
00526     /* prevent clipping - would only happen if fov > ~127 degrees, at
00527        fov = 2.0 * atan(2.0) */
00528 
00529     if (*siz > Gd.nearclip) {
00530         *siz = Gd.nearclip;
00531     }
00532 
00533     GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir);
00534 
00535     pos[X] = Gv.from_to[FROM][X] + dir[X] * dist;
00536     pos[Y] = Gv.from_to[FROM][Y] + dir[Y] * dist;
00537     pos[Z] = Gv.from_to[FROM][Z] + dir[Z] * dist;
00538 
00539     return;
00540 }
00541 
00542 
00554 void GS_set_Narrow(int *pt, int id, float *pos2)
00555 {
00556     geosurf *gs;
00557     float x, y, z;
00558     GLdouble modelMatrix[16], projMatrix[16];
00559     GLint viewport[4];
00560 
00561     if (GS_get_selected_point_on_surface(pt[X], pt[Y], &id, &x, &y, &z)) {
00562         gs = gs_get_surf(id);
00563         if (gs) {
00564             z = gs->zmax;
00565             pos2[X] = (float)x - gs->ox + gs->x_trans;
00566             pos2[Y] = (float)y - gs->oy + gs->y_trans;
00567             pos2[Z] = (float)z + gs->z_trans;
00568 
00569             return;
00570         }
00571     }
00572     else {
00573         gs = gs_get_surf(id);
00574 
00575         /* Need to get model matrix, etc 
00576          * to run gluUnProject
00577          */
00578         gsd_pushmatrix();
00579         gsd_do_scale(1);
00580         glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
00581         glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
00582         glGetIntegerv(GL_VIEWPORT, viewport);
00583 
00584         if (gs) {
00585             GLdouble out_near[3], out_far[3];
00586             GLdouble factor;
00587             GLdouble out[3];
00588 
00589             z = (float)gs->zmax + gs->z_trans;
00590 
00591             gluUnProject((GLdouble) pt[X], (GLdouble) pt[Y], (GLdouble) 0.,
00592                          modelMatrix, projMatrix, viewport,
00593                          &out_near[X], &out_near[Y], &out_near[Z]);
00594             gluUnProject((GLdouble) pt[X], (GLdouble) pt[Y], (GLdouble) 1.,
00595                          modelMatrix, projMatrix, viewport,
00596                          &out_far[X], &out_far[Y], &out_far[Z]);
00597 
00598             glPopMatrix();
00599 
00600             factor = (out_near[Z] - z) / (out_near[Z] - out_far[Z]);
00601 
00602             out[X] = out_near[X] - ((out_near[X] - out_far[X]) * factor);
00603             out[Y] = out_near[Y] - ((out_near[Y] - out_far[Y]) * factor);
00604             out[Z] = z;
00605 
00606             pos2[X] = (float)out[X];
00607             pos2[Y] = (float)out[Y];
00608             pos2[Z] = (float)out[Z];
00609 
00610             return;
00611 
00612         }
00613     }
00614     return;
00615 }
00616 
00623 void GS_draw_X(int id, float *pt)
00624 {
00625     geosurf *gs;
00626     Point3 pos;
00627     float siz;
00628 
00629     if ((gs = gs_get_surf(id))) {
00630         GS_get_longdim(&siz);
00631         siz /= 200.;
00632         pos[X] = pt[X] - gs->ox;
00633         pos[Y] = pt[Y] - gs->oy;
00634         _viewcell_tri_interp(gs, pos);
00635 
00636         gsd_pushmatrix();
00637 
00638         gsd_do_scale(1);
00639         gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
00640         gsd_linewidth(1);
00641 
00642         if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) {
00643             pos[Z] = gs->att[ATT_TOPO].constant;
00644             gs = NULL;          /* tells gpd_obj to use given Z val */
00645         }
00646 
00647         gpd_obj(gs, Gd.bgcol, siz, ST_GYRO, pos);
00648         gsd_flush();
00649 
00650         gsd_popmatrix();
00651     }
00652 
00653     return;
00654 }
00655 
00662 void GS_draw_line_onsurf(int id, float x1, float y1, float x2, float y2)
00663 {
00664     float p1[2], p2[2];
00665     geosurf *gs;
00666 
00667     if ((gs = gs_get_surf(id))) {
00668         p1[X] = x1 - gs->ox;
00669         p1[Y] = y1 - gs->oy;
00670         p2[X] = x2 - gs->ox;
00671         p2[Y] = y2 - gs->oy;
00672 
00673         gsd_pushmatrix();
00674 
00675         gsd_do_scale(1);
00676         gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
00677         gsd_linewidth(1);
00678 
00679         gsd_color_func(GS_default_draw_color());
00680         gsd_line_onsurf(gs, p1, p2);
00681 
00682         gsd_popmatrix();
00683         gsd_flush();
00684     }
00685 
00686     return;
00687 }
00688 
00701 int GS_draw_nline_onsurf(int id, float x1, float y1, float x2, float y2,
00702                          float *lasp, int n)
00703 {
00704     float p1[2], p2[2];
00705     geosurf *gs;
00706     int ret = 0;
00707 
00708     if ((gs = gs_get_surf(id))) {
00709         p1[X] = x1 - gs->ox;
00710         p1[Y] = y1 - gs->oy;
00711         p2[X] = x2 - gs->ox;
00712         p2[Y] = y2 - gs->oy;
00713 
00714         gsd_pushmatrix();
00715 
00716         gsd_do_scale(1);
00717         gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
00718         gsd_linewidth(1);
00719         gsd_color_func(GS_default_draw_color());
00720         ret = gsd_nline_onsurf(gs, p1, p2, lasp, n);
00721         gsd_surf2real(gs, lasp);
00722 
00723         gsd_popmatrix();
00724         gsd_flush();
00725     }
00726 
00727     return (ret);
00728 }
00729 
00739 void GS_draw_flowline_at_xy(int id, float x, float y)
00740 {
00741     geosurf *gs;
00742     float nv[3], pdir[2], mult;
00743     float p1[2], p2[2], next[2];
00744     int i = 0;
00745 
00746     if ((gs = gs_get_surf(id))) {
00747         p1[X] = x;
00748         p1[Y] = y;
00749         /* multiply by 1.5 resolutions to ensure a crossing ? */
00750         mult = .1 * (VXRES(gs) > VYRES(gs) ? VXRES(gs) : VYRES(gs));
00751 
00752         GS_coordpair_repeats(p1, p1, 50);
00753 
00754         while (1 == GS_get_norm_at_xy(id, p1[X], p1[Y], nv)) {
00755             if (nv[Z] == 1.0) {
00756                 if (pdir[X] == 0.0 && pdir[Y] == 0.0) {
00757                     break;
00758                 }
00759 
00760                 p2[X] = p1[X] + (pdir[X] * mult);
00761                 p2[Y] = p1[Y] + (pdir[Y] * mult);
00762             }
00763             else {
00764                 /* use previous direction */
00765                 GS_v2norm(nv);
00766                 p2[X] = p1[X] + (nv[X] * mult);
00767                 p2[Y] = p1[Y] + (nv[Y] * mult);
00768                 pdir[X] = nv[X];
00769                 pdir[Y] = nv[Y];
00770             }
00771 
00772             if (i > 2000) {
00773                 break;
00774             }
00775 
00776             if (GS_coordpair_repeats(p1, p2, 0)) {
00777                 break;
00778             }
00779 
00780             /* Think about this: */
00781             /* degenerate line means edge or level edge ? */
00782             /* next is filled with last point drawn */
00783             if (2 > GS_draw_nline_onsurf(id, p1[X], p1[Y],
00784                                          p2[X], p2[Y], next, 3)) {
00785                 break;
00786             }
00787 
00788             p1[X] = next[X];
00789             p1[Y] = next[Y];
00790         }
00791 
00792         G_debug(3, "GS_draw_flowline_at_xy(): dir: %f %f", nv[X], nv[Y]);
00793     }
00794 
00795     return;
00796 }
00797 
00806 void GS_draw_fringe(int id, unsigned long clr, float elev, int *where)
00807 {
00808     geosurf *gs;
00809 
00810     G_debug(3, "GS_draw_fringe(): id: %d clr: %ld elev %f edges: %d %d %d %d",
00811             id, clr, elev, where[0], where[1], where[2], where[3]);
00812     if ((gs = gs_get_surf(id)))
00813         gsd_display_fringe(gs, clr, elev, where);
00814 
00815 }
00816 
00817 
00831 int GS_draw_legend(const char *name, GLuint fontbase, int size, int *flags,
00832                    float *range, int *pt)
00833 {
00834     int list_no;
00835 
00836     list_no = gsd_put_legend(name, fontbase, size, flags, range, pt);
00837 
00838     return (list_no);
00839 }
00840 
00849 void GS_draw_list(GLuint list_id)
00850 {
00851     gsd_calllist(list_id);
00852     glFlush();
00853     return;
00854 }
00855 
00862 void GS_draw_all_list(void)
00863 {
00864     gsd_calllists(0);           /* not sure if 0 is right - MN */
00865     glFlush();
00866     return;
00867 }
00868 
00874 void GS_delete_list(GLuint list_id)
00875 {
00876     gsd_deletelist(list_id, 1);
00877 
00878     return;
00879 }
00880 
00884 void GS_draw_lighting_model1(void)
00885 {
00886     static float center[3];
00887     float tcenter[3];
00888 
00889     if (!Modelshowing) {
00890         GS_get_modelposition1(center);
00891     }
00892 
00893     GS_v3eq(tcenter, center);
00894 
00895     gsd_zwritemask(0x0);
00896     gsd_backface(1);
00897 
00898     gsd_colormode(CM_AD);
00899     gsd_shademodel(DM_GOURAUD);
00900     gsd_pushmatrix();
00901     gsd_do_scale(1);
00902 
00903     if (Gv.vert_exag) {
00904         tcenter[Z] *= Gv.vert_exag;
00905         gsd_scale(1.0, 1.0, 1. / Gv.vert_exag);
00906     }
00907 
00908     gsd_drawsphere(tcenter, 0xDDDDDD, (float)(Longdim / 10.));
00909     gsd_popmatrix();
00910     Modelshowing = 1;
00911 
00912     gsd_backface(0);
00913     gsd_zwritemask(0xffffffff);
00914 
00915     return;
00916 }
00917 
00924 void GS_draw_lighting_model(void)
00925 {
00926     static float center[3], size;
00927     float tcenter[3], tsize;
00928     int i, wason[MAX_CPLANES];
00929 
00930     gsd_get_cplanes_state(wason);
00931 
00932     for (i = 0; i < MAX_CPLANES; i++) {
00933         if (wason[i]) {
00934             gsd_cplane_off(i);
00935         }
00936     }
00937 
00938 
00939     if (!Modelshowing) {
00940         GS_get_modelposition(&size, center);
00941     }
00942 
00943     GS_v3eq(tcenter, center);
00944     tsize = size;
00945 
00946     gsd_zwritemask(0x0);
00947     gsd_backface(1);
00948 
00949     gsd_colormode(CM_DIFFUSE);
00950     gsd_shademodel(DM_GOURAUD);
00951     gsd_pushmatrix();
00952     gsd_drawsphere(tcenter, 0xDDDDDD, tsize);
00953     gsd_popmatrix();
00954     Modelshowing = 1;
00955 
00956     gsd_backface(0);
00957     gsd_zwritemask(0xffffffff);
00958 
00959     for (i = 0; i < MAX_CPLANES; i++) {
00960         if (wason[i]) {
00961             gsd_cplane_on(i);
00962         }
00963     }
00964 
00965     gsd_flush();
00966 
00967     return;
00968 }
00969 
00980 int GS_update_curmask(int id)
00981 {
00982     geosurf *gs;
00983 
00984     gs = gs_get_surf(id);
00985     return (gs_update_curmask(gs));
00986 }
00987 
00998 int GS_is_masked(int id, float *pt)
00999 {
01000     geosurf *gs;
01001     Point3 tmp;
01002 
01003     if ((gs = gs_get_surf(id))) {
01004         tmp[X] = pt[X] - gs->ox;
01005         tmp[Y] = pt[Y] - gs->oy;
01006 
01007         return (gs_point_is_masked(gs, tmp));
01008     }
01009 
01010     return (-1);
01011 }
01012 
01016 void GS_unset_SDsurf(void)
01017 {
01018     gsdiff_set_SDref(NULL);
01019     SDref_surf = 0;
01020 
01021     return;
01022 }
01023 
01032 int GS_set_SDsurf(int id)
01033 {
01034     geosurf *gs;
01035 
01036     if ((gs = gs_get_surf(id))) {
01037         gsdiff_set_SDref(gs);
01038         SDref_surf = id;
01039 
01040         return (1);
01041     }
01042 
01043     return (0);
01044 }
01045 
01053 int GS_set_SDscale(float scale)
01054 {
01055     gsdiff_set_SDscale(scale);
01056 
01057     return (1);
01058 }
01059 
01068 int GS_get_SDsurf(int *id)
01069 {
01070     geosurf *gs;
01071 
01072     if ((gs = gsdiff_get_SDref())) {
01073         *id = SDref_surf;
01074 
01075         return (1);
01076     }
01077 
01078     return (0);
01079 }
01080 
01088 int GS_get_SDscale(float *scale)
01089 {
01090     *scale = gsdiff_get_SDscale();
01091 
01092     return (1);
01093 }
01094 
01102 int GS_update_normals(int id)
01103 {
01104     geosurf *gs;
01105 
01106     gs = gs_get_surf(id);
01107 
01108     return (gs_calc_normals(gs));
01109 }
01110 
01123 int GS_get_att(int id, int att, int *set, float *constant, char *mapname)
01124 {
01125     int src;
01126     geosurf *gs;
01127 
01128     gs = gs_get_surf(id);
01129     if (gs) {
01130         if (-1 != (src = gs_get_att_src(gs, att))) {
01131             *set = src;
01132 
01133             if (src == CONST_ATT) {
01134                 *constant = gs->att[att].constant;
01135             }
01136             else if (src == MAP_ATT) {
01137                 strcpy(mapname, gsds_get_name(gs->att[att].hdata));
01138             }
01139 
01140             return (1);
01141         }
01142 
01143         return (-1);
01144     }
01145 
01146     return (-1);
01147 }
01148 
01166 int GS_get_cat_at_xy(int id, int att, char *catstr, float x, float y)
01167 {
01168     int offset, drow, dcol, vrow, vcol;
01169     float ftmp, pt[3];
01170     typbuff *buff;
01171     geosurf *gs;
01172 
01173     *catstr = '\0';
01174     gs = gs_get_surf(id);
01175 
01176     if (NULL == gs) {
01177         return -1;
01178     }
01179 
01180     pt[X] = x;
01181     pt[Y] = y;
01182 
01183     gsd_real2surf(gs, pt);
01184     if (gs_point_is_masked(gs, pt)) {
01185         return -1;
01186     }
01187 
01188     if (!in_vregion(gs, pt)) {
01189         return -1;
01190     }
01191 
01192     if (MAP_ATT != gs_get_att_src(gs, att)) {
01193         sprintf(catstr, _("no category info"));
01194         return -1;
01195     }
01196 
01197     buff = gs_get_att_typbuff(gs, att, 0);
01198 
01199     vrow = Y2VROW(gs, pt[Y]);
01200     vcol = X2VCOL(gs, pt[X]);
01201     drow = VROW2DROW(gs, vrow);
01202     dcol = VCOL2DCOL(gs, vcol);
01203 
01204     offset = DRC2OFF(gs, drow, dcol);
01205     
01206     if (GET_MAPATT(buff, offset, ftmp)) {
01207         return
01208             (Gs_get_cat_label(gsds_get_name(gs->att[att].hdata),
01209                               drow, dcol, catstr));
01210     }
01211 
01212     sprintf(catstr, _("no data"));
01213 
01214     return 1;
01215 }
01216 
01229 int GS_get_norm_at_xy(int id, float x, float y, float *nv)
01230 {
01231     int offset, drow, dcol, vrow, vcol;
01232     float pt[3];
01233     geosurf *gs;
01234 
01235     gs = gs_get_surf(id);
01236 
01237     if (NULL == gs) {
01238         return (-1);
01239     }
01240 
01241     if (gs->norm_needupdate) {
01242         gs_calc_normals(gs);
01243     }
01244 
01245     pt[X] = x;
01246     pt[Y] = y;
01247 
01248     gsd_real2surf(gs, pt);
01249     if (gs_point_is_masked(gs, pt)) {
01250         return (-1);
01251     }
01252 
01253     if (!in_vregion(gs, pt)) {
01254         return (-1);
01255     }
01256 
01257     vrow = Y2VROW(gs, pt[Y]);
01258     vcol = X2VCOL(gs, pt[X]);
01259     drow = VROW2DROW(gs, vrow);
01260     dcol = VCOL2DCOL(gs, vcol);
01261 
01262     offset = DRC2OFF(gs, drow, dcol);
01263 
01264     if (gs->norms) {
01265         FNORM(gs->norms[offset], nv);
01266     }
01267     else {
01268         /* otherwise must be a constant */
01269         nv[0] = 0.0;
01270         nv[1] = 0.0;
01271         nv[2] = 1.0;
01272     }
01273 
01274     return (1);
01275 }
01276 
01293 int GS_get_val_at_xy(int id, int att, char *valstr, float x, float y)
01294 {
01295     int offset, drow, dcol, vrow, vcol;
01296     float ftmp, pt[3];
01297     typbuff *buff;
01298     geosurf *gs;
01299 
01300     *valstr = '\0';
01301     gs = gs_get_surf(id);
01302     
01303     if (NULL == gs) {
01304         return -1;
01305     }
01306 
01307     pt[X] = x;
01308     pt[Y] = y;
01309 
01310     gsd_real2surf(gs, pt);
01311 
01312     if (gs_point_is_masked(gs, pt)) {
01313         return -1;
01314     }
01315 
01316     if (!in_vregion(gs, pt)) {
01317         return (-1);
01318     }
01319 
01320     if (CONST_ATT == gs_get_att_src(gs, att)) {
01321         if (att == ATT_COLOR) {
01322             int r, g, b, i;
01323 
01324             i = gs->att[att].constant;
01325             sprintf(valstr, "R%d G%d B%d",
01326                     INT_TO_RED(i, r), INT_TO_GRN(i, g), INT_TO_BLU(i, b));
01327         }
01328         else {
01329             sprintf(valstr, "%f", gs->att[att].constant);
01330         }
01331 
01332         return 1;
01333     }
01334     else if (MAP_ATT != gs_get_att_src(gs, att)) {
01335         return -1;
01336     }
01337 
01338     buff = gs_get_att_typbuff(gs, att, 0);
01339 
01340     vrow = Y2VROW(gs, pt[Y]);
01341     vcol = X2VCOL(gs, pt[X]);
01342     drow = VROW2DROW(gs, vrow);
01343     dcol = VCOL2DCOL(gs, vcol);
01344 
01345     offset = DRC2OFF(gs, drow, dcol);
01346 
01347     if (GET_MAPATT(buff, offset, ftmp)) {
01348         if (att == ATT_COLOR) {
01349             int r, g, b, i;
01350 
01351             i = gs_mapcolor(gs_get_att_typbuff(gs, ATT_COLOR, 0),
01352                             &(gs->att[ATT_COLOR]), offset);
01353             sprintf(valstr, "R%d G%d B%d",
01354                     INT_TO_RED(i, r), INT_TO_GRN(i, g), INT_TO_BLU(i, b));
01355         }
01356         else {
01357             sprintf(valstr, "%f", ftmp);
01358         }
01359 
01360         return (1);
01361     }
01362 
01363     sprintf(valstr, "NULL");
01364 
01365     return (1);
01366 }
01367 
01376 int GS_unset_att(int id, int att)
01377 {
01378     geosurf *gs;
01379 
01380     gs = gs_get_surf(id);
01381     gs->mask_needupdate = 1;
01382 
01383     return (gs_set_att_src(gs, att, NOTSET_ATT));
01384 }
01385 
01395 int GS_set_att_const(int id, int att, float constant)
01396 {
01397     geosurf *gs;
01398     int ret;
01399 
01400     gs = gs_get_surf(id);
01401     ret = (gs_set_att_const(gs, att, constant));
01402 
01403     Gs_update_attrange(gs, att);
01404 
01405     return (ret);
01406 }
01407 
01419 int GS_set_maskmode(int id, int mode)
01420 {
01421     geosurf *gs;
01422 
01423     gs = gs_get_surf(id);
01424 
01425     if (gs) {
01426         gs->att[ATT_MASK].constant = mode;
01427         gs->mask_needupdate = 1;
01428 
01429         return (mode);
01430     }
01431 
01432     return (-1);
01433 }
01434 
01444 int GS_get_maskmode(int id, int *mode)
01445 {
01446     geosurf *gs;
01447 
01448     gs = gs_get_surf(id);
01449 
01450     if (gs) {
01451         *mode = gs->att[ATT_MASK].constant;
01452 
01453         return (1);
01454     }
01455 
01456     return (-1);
01457 }
01458 
01468 int GS_Set_ClientData(int id, void *clientd)
01469 {
01470     geosurf *gs;
01471 
01472     gs = gs_get_surf(id);
01473     if (gs) {
01474         gs->clientdata = clientd;
01475 
01476         return (1);
01477     }
01478 
01479     return (-1);
01480 }
01481 
01490 void *GS_Get_ClientData(int id)
01491 {
01492     geosurf *gs;
01493 
01494     gs = gs_get_surf(id);
01495     if (gs) {
01496         return (gs->clientdata);
01497     }
01498 
01499     return (NULL);
01500 }
01501 
01507 int GS_num_surfs(void)
01508 {
01509     return (gs_num_surfaces());
01510 }
01511 
01522 int *GS_get_surf_list(int *numsurfs)
01523 {
01524     int i, *ret;
01525 
01526     *numsurfs = Next_surf;
01527 
01528     if (Next_surf) {
01529         ret = (int *)G_malloc(Next_surf * sizeof(int));
01530 
01531         for (i = 0; i < Next_surf; i++) {
01532             ret[i] = Surf_ID[i];
01533         }
01534 
01535         return (ret);
01536     }
01537 
01538     return (NULL);
01539 }
01540 
01549 int GS_delete_surface(int id)
01550 {
01551     int i, j, found = 0;
01552 
01553     G_debug(3, "GS_delete_surface");
01554 
01555     if (GS_surf_exists(id)) {
01556         gs_delete_surf(id);
01557 
01558         for (i = 0; i < Next_surf && !found; i++) {
01559             if (Surf_ID[i] == id) {
01560                 found = 1;
01561 
01562                 for (j = i; j < Next_surf; j++) {
01563                     Surf_ID[j] = Surf_ID[j + 1];
01564                 }
01565             }
01566         }
01567 
01568         gv_update_drapesurfs();
01569 
01570         if (found) {
01571             --Next_surf;
01572             return (1);
01573         }
01574     }
01575 
01576     return (-1);
01577 }
01578 
01579 
01590 int GS_load_att_map(int id, const char *filename, int att)
01591 {
01592     geosurf *gs;
01593     unsigned int changed;
01594     unsigned int atty;
01595     const char *mapset;
01596     struct Cell_head rast_head;
01597     int reuse, begin, hdata, ret, neg, has_null;
01598     typbuff *tbuff;
01599 
01600     G_debug(3, "GS_load_att_map(): map=%s", filename);
01601 
01602     reuse = ret = neg = has_null = 0;
01603     gs = gs_get_surf(id);
01604 
01605     if (NULL == gs) {
01606         return -1;
01607     }
01608 
01609     gs->mask_needupdate = (ATT_MASK == att || ATT_TOPO == att ||
01610                            (gs->nz_topo && ATT_TOPO == att) ||
01611                            (gs->nz_color && ATT_COLOR == att));
01612 
01613     gs_set_att_src(gs, att, MAP_ATT);
01614 
01615     /* Check against maps already loaded in memory   */
01616     /* if to be color attribute:
01617        - if packed color for another surface, OK to reuse
01618        - if unchanged, ok to reuse IF it's of type char (will have lookup)
01619      */
01620     begin = hdata = 1;
01621 
01622     /* Get MAPSET to ensure names are fully qualified */
01623     mapset = G_find_cell2(filename, "");
01624     if (mapset == NULL) {
01625         /* Check for valid filename */
01626         G_warning("Raster map <%s> not found", filename);
01627         return -1;
01628     }
01629     
01630     /* Check to see if map is in Region */
01631     G_get_cellhd(filename, mapset, &rast_head);
01632     if (rast_head.north <= wind.south ||
01633         rast_head.south >= wind.north ||
01634         rast_head.east <= wind.west || rast_head.west >= wind.east) {
01635 
01636         G_warning(_("Raster map <%s> is outside of current region. Load failed."),
01637                   G_fully_qualified_name(filename, mapset));
01638     }
01639 
01640     while (!reuse && (0 < hdata)) {
01641         changed = CF_COLOR_PACKED;
01642         atty = ATTY_FLOAT | ATTY_CHAR | ATTY_INT | ATTY_SHORT | ATTY_MASK;
01643 
01644         if (0 < (hdata = gsds_findh(filename, &changed, &atty, begin))) {
01645 
01646             G_debug(3, "GS_load_att_map(): %s already has data handle %d.CF=%x",
01647                     filename, hdata, changed);
01648 
01649             /* handle found */
01650             if (ATT_COLOR == att) {
01651                 if ((changed == CF_COLOR_PACKED) ||
01652                     (!changed && atty == ATTY_CHAR)) {
01653                     reuse = 1;
01654                 }
01655             }
01656             else if (atty == ATTY_MASK && att != ATT_MASK) {
01657                 reuse = 0;
01658                 /* should also free mask data & share new - but need backward
01659                    reference? */
01660             }
01661             else if (!changed) {
01662                 reuse = 1;
01663             }
01664         }
01665 
01666         begin = 0;
01667     }
01668 
01669     if (reuse) {
01670         gs->att[att].hdata = hdata;
01671         gs_set_att_type(gs, att, atty); /* ?? */
01672 
01673         /* free lookup  & set to NULL! */
01674         if (atty == ATTY_INT) {
01675             if (gs->att[att].lookup) {
01676                 free(gs->att[att].lookup);
01677                 gs->att[att].lookup = NULL;
01678             }
01679         }
01680         /* TODO: FIX THIS stuff with lookup sharing! */
01681 
01682         G_debug(3, "GS_load_att_map(): %s is being reused. hdata=%d",
01683                 filename, hdata);
01684     }
01685     else {
01686         G_debug(3, "GS_load_att_map(): %s not loaded in correct form - loading now",
01687                 filename);
01688 
01689         /* not loaded - need to get new dataset handle */
01690         gs->att[att].hdata = gsds_newh(filename);
01691 
01692         tbuff = gs_get_att_typbuff(gs, att, 1);
01693 
01694         /* TODO: Provide mechanism for loading certain attributes at
01695            specified sizes, allow to scale or cap, or scale non-zero */
01696         if (ATT_MASK == att) {
01697             atty = ATTY_MASK;
01698         }
01699         else {
01700             atty = Gs_numtype(filename, &neg);
01701         }
01702 
01703 #ifdef MAYBE_LATER
01704         if (att == ATT_COLOR && atty == ATTY_SHORT) {
01705             atty = (neg ? ATTY_INT : ATTY_SHORT);
01706         }
01707 #endif
01708 
01709         if (att == ATT_COLOR && atty == ATTY_SHORT) {
01710             atty = ATTY_INT;
01711         }
01712 
01713         if (0 > gs_malloc_att_buff(gs, att, ATTY_NULL)) {
01714             G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
01715         }
01716 
01717         switch (atty) {
01718         case ATTY_MASK:
01719             if (0 > gs_malloc_att_buff(gs, att, ATTY_MASK)) {
01720                 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
01721             }
01722 
01723             ret = Gs_loadmap_as_bitmap(&wind, filename, tbuff->bm);
01724             
01725             break;
01726         case ATTY_CHAR:
01727             if (0 > gs_malloc_att_buff(gs, att, ATTY_CHAR)) {
01728                 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
01729             }
01730 
01731             ret = Gs_loadmap_as_char(&wind, filename, tbuff->cb,
01732                                      tbuff->nm, &has_null);
01733 
01734             break;
01735         case ATTY_SHORT:
01736             if (0 > gs_malloc_att_buff(gs, att, ATTY_SHORT)) {
01737                 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
01738             }
01739 
01740             ret = Gs_loadmap_as_short(&wind, filename, tbuff->sb,
01741                                       tbuff->nm, &has_null);
01742             break;
01743         case ATTY_FLOAT:
01744             if (0 > gs_malloc_att_buff(gs, att, ATTY_FLOAT)) {
01745                 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
01746             }
01747 
01748             ret = Gs_loadmap_as_float(&wind, filename, tbuff->fb,
01749                                       tbuff->nm, &has_null);
01750 
01751             break;
01752         case ATTY_INT:
01753         default:
01754             if (0 > gs_malloc_att_buff(gs, att, ATTY_INT)) {
01755                 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
01756             }
01757 
01758             ret = Gs_loadmap_as_int(&wind, filename, tbuff->ib,
01759                                     tbuff->nm, &has_null);
01760             break;
01761 
01762         }                       /* Done with switch */
01763 
01764         if (ret == -1) {
01765             gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL);
01766             return -1;
01767         }
01768 
01769         G_debug(4, "  has_null=%d", has_null);
01770 
01771         if (!has_null) {
01772             gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL);
01773         }
01774         else {
01775             gs_update_curmask(gs);
01776         }
01777 
01778     }                           /* end if not reuse */
01779 
01780     if (ATT_COLOR == att) {
01781 #ifdef MAYBE_LATER
01782         if (ATTY_INT == atty) {
01783             Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols);
01784             gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
01785             gs->att[att].lookup = NULL;
01786         }
01787         else {
01788             gs_malloc_lookup(gs, att);
01789             Gs_build_lookup(filename, gs->att[att].lookup);
01790         }
01791 #else
01792 
01793         if (ATTY_CHAR == atty) {
01794             if (!gs->att[att].lookup) {
01795                 /* might already exist if reusing */
01796                 gs_malloc_lookup(gs, att);
01797                 Gs_build_256lookup(filename, gs->att[att].lookup);
01798             }
01799         }
01800         else if (ATTY_FLOAT == atty) {
01801             if (!reuse) {
01802                 if (0 > gs_malloc_att_buff(gs, att, ATTY_INT)) {
01803                     G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map"));
01804                 }
01805 
01806                 Gs_pack_colors_float(filename, tbuff->fb, tbuff->ib,
01807                                      gs->rows, gs->cols);
01808                 gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
01809                 gsds_free_data_buff(gs->att[att].hdata, ATTY_FLOAT);
01810                 gs->att[att].lookup = NULL;
01811             }
01812         }
01813         else {
01814             if (!reuse) {
01815                 Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols);
01816                 gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
01817                 gs->att[att].lookup = NULL;
01818             }
01819         }
01820 #endif
01821     }
01822 
01823     if (ATT_TOPO == att) {
01824         gs_init_normbuff(gs);
01825         /* S_DIFF: should also check here to see if this surface is a
01826            reference surface for scaled differences, if so update references
01827            to it */
01828     }
01829 
01830     if (ret < 0) {
01831         G_warning(_("Loading failed"));
01832     }
01833 
01834     if (-1 == Gs_update_attrange(gs, att)) {
01835         G_warning(_("Error finding range"));
01836     }
01837 
01838     return ret;
01839 }
01840 
01846 void GS_draw_surf(int id)
01847 {
01848     geosurf *gs;
01849 
01850     G_debug(3, "GS_draw_surf(): id=%d", id);
01851 
01852     gs = gs_get_surf(id);
01853     if (gs) {
01854         gsd_shademodel(gs->draw_mode & DM_GOURAUD);
01855 
01856         if (gs->draw_mode & DM_POLY) {
01857             gsd_surf(gs);
01858         }
01859 
01860         if (gs->draw_mode & DM_WIRE) {
01861             gsd_wire_surf(gs);
01862         }
01863 
01864         /* TODO: write wire/poly draw routines */
01865         if (gs->draw_mode & DM_WIRE_POLY) {
01866             gsd_surf(gs);
01867             gsd_wire_surf(gs);
01868         }
01869     }
01870 
01871     return;
01872 }
01873 
01881 void GS_draw_wire(int id)
01882 {
01883     geosurf *gs;
01884 
01885     G_debug(3, "GS_draw_wire(): id=%d", id);
01886 
01887     gs = gs_get_surf(id);
01888 
01889     if (gs) {
01890         gsd_wire_surf(gs);
01891     }
01892 
01893     return;
01894 }
01895 
01901 void GS_alldraw_wire(void)
01902 {
01903     geosurf *gs;
01904     int i;
01905 
01906     for (i = 0; i < Next_surf; i++) {
01907         if ((gs = gs_get_surf(Surf_ID[i]))) {
01908             gsd_wire_surf(gs);
01909         }
01910     }
01911 
01912     return;
01913 }
01914 
01918 void GS_alldraw_surf(void)
01919 {
01920     int i;
01921 
01922     for (i = 0; i < Next_surf; i++) {
01923         GS_draw_surf(Surf_ID[i]);
01924     }
01925 
01926     return;
01927 }
01928 
01935 void GS_set_exag(int id, float exag)
01936 {
01937     geosurf *gs;
01938 
01939     G_debug(3, "GS_set_exag");
01940 
01941     gs = gs_get_surf(id);
01942 
01943     if (gs) {
01944         if (gs->z_exag != exag) {
01945             gs->norm_needupdate = 1;
01946         }
01947 
01948         gs->z_exag = exag;
01949     }
01950 
01951     return;
01952 }
01953 
01959 void GS_set_global_exag(float exag)
01960 {
01961 
01962     G_debug(3, "GS_set_global_exag");
01963 
01964     Gv.vert_exag = exag;
01965     /* GL_NORMALIZE */
01966     /* Only need to update norms gs_norms.c
01967      * if exag is used in norm equation which
01968      * it is not! If GL_NORMALIZE is disabled
01969      * will need to include.
01970      gs_setall_norm_needupdate();
01971      */
01972 
01973     return;
01974 }
01975 
01981 float GS_global_exag(void)
01982 {
01983     G_debug(3, "GS_global_exag(): %g", Gv.vert_exag);
01984 
01985     return (Gv.vert_exag);
01986 }
01987 
01996 void GS_set_wire_color(int id, int colr)
01997 {
01998     geosurf *gs;
01999 
02000     G_debug(3, "GS_set_wire_color");
02001 
02002     gs = gs_get_surf(id);
02003 
02004     if (gs) {
02005         gs->wire_color = colr;
02006     }
02007 
02008     return;
02009 }
02010 
02020 int GS_get_wire_color(int id, int *colr)
02021 {
02022     geosurf *gs;
02023 
02024     gs = gs_get_surf(id);
02025 
02026     if (gs) {
02027         *colr = gs->wire_color;
02028 
02029         return (1);
02030     }
02031 
02032     return (-1);
02033 }
02034 
02043 int GS_setall_drawmode(int mode)
02044 {
02045     int i;
02046 
02047     for (i = 0; i < Next_surf; i++) {
02048         if (0 != GS_set_drawmode(Surf_ID[i], mode)) {
02049             return (-1);
02050         }
02051     }
02052 
02053     return (0);
02054 }
02055 
02065 int GS_set_drawmode(int id, int mode)
02066 {
02067     geosurf *gs;
02068 
02069     G_debug(3, "GS_set_drawmode(): id=%d mode=%d", id, mode);
02070 
02071     gs = gs_get_surf(id);
02072 
02073     if (gs) {
02074         gs->draw_mode = mode;
02075 
02076         return (0);
02077     }
02078 
02079     return (-1);
02080 }
02081 
02091 int GS_get_drawmode(int id, int *mode)
02092 {
02093     geosurf *gs;
02094 
02095     gs = gs_get_surf(id);
02096 
02097     if (gs) {
02098         *mode = gs->draw_mode;
02099 
02100         return (1);
02101     }
02102 
02103     return (-1);
02104 }
02105 
02113 void GS_set_nozero(int id, int att, int mode)
02114 {
02115     geosurf *gs;
02116 
02117     G_debug(3, "GS_set_nozero");
02118 
02119     gs = gs_get_surf(id);
02120 
02121     if (gs) {
02122         if (att == ATT_TOPO) {
02123             gs->nz_topo = mode;
02124             gs->mask_needupdate = 1;
02125         }
02126 
02127         if (att == ATT_COLOR) {
02128             gs->nz_color = mode;
02129             gs->mask_needupdate = 1;
02130         }
02131     }
02132 
02133     return;
02134 }
02135 
02146 int GS_get_nozero(int id, int att, int *mode)
02147 {
02148     geosurf *gs;
02149 
02150     G_debug(3, "GS_set_nozero");
02151 
02152     gs = gs_get_surf(id);
02153 
02154     if (gs) {
02155         if (att == ATT_TOPO) {
02156             *mode = gs->nz_topo;
02157         }
02158         else if (att == ATT_COLOR) {
02159             *mode = gs->nz_color;
02160         }
02161         else {
02162             return (-1);
02163         }
02164 
02165         return (1);
02166     }
02167 
02168     return (-1);
02169 }
02170 
02180 int GS_setall_drawres(int xres, int yres, int xwire, int ywire)
02181 {
02182     int i;
02183 
02184     for (i = 0; i < Next_surf; i++) {
02185         if (0 != GS_set_drawres(Surf_ID[i], xres, yres, xwire, ywire)) {
02186             return (-1);
02187         }
02188     }
02189 
02190     return (0);
02191 }
02192 
02203 int GS_set_drawres(int id, int xres, int yres, int xwire, int ywire)
02204 {
02205     geosurf *gs;
02206 
02207     G_debug(3, "GS_set_drawres() id=%d xyres=%d/%d xywire=%d/%d",
02208             id, xres, yres, xwire, ywire);
02209 
02210     if (xres < 1 || yres < 1 || xwire < 1 || ywire < 1) {
02211         return (-1);
02212     }
02213 
02214     gs = gs_get_surf(id);
02215 
02216     if (gs) {
02217         if (gs->x_mod != xres || gs->y_mod != yres) {
02218             gs->norm_needupdate = 1;
02219         }
02220 
02221         gs->x_mod = xres;
02222         gs->y_mod = yres;
02223         gs->x_modw = xwire;
02224         gs->y_modw = ywire;
02225     }
02226 
02227     return (0);
02228 }
02229 
02237 void GS_get_drawres(int id, int *xres, int *yres, int *xwire, int *ywire)
02238 {
02239     geosurf *gs;
02240 
02241     G_debug(3, "GS_get_drawres");
02242 
02243     gs = gs_get_surf(id);
02244 
02245     if (gs) {
02246         *xres = gs->x_mod;
02247         *yres = gs->y_mod;
02248         *xwire = gs->x_modw;
02249         *ywire = gs->y_modw;
02250     }
02251 
02252     return;
02253 }
02254 
02261 void GS_get_dims(int id, int *rows, int *cols)
02262 {
02263     geosurf *gs;
02264 
02265     gs = gs_get_surf(id);
02266 
02267     if (gs) {
02268         *rows = gs->rows;
02269         *cols = gs->cols;
02270     }
02271 
02272     return;
02273 }
02274 
02288 int GS_get_exag_guess(int id, float *exag)
02289 {
02290     geosurf *gs;
02291     float guess;
02292 
02293     gs = gs_get_surf(id);
02294     guess = 1.0;
02295 
02296     /* if gs is type const return guess = 1.0 */
02297     if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) {
02298         return (1);
02299     }
02300 
02301     if (gs) {
02302         if (gs->zrange_nz == 0.0) {
02303             *exag = 0.0;
02304 
02305             return (1);
02306         }
02307 
02308         G_debug(3, "GS_get_exag_guess(): %f %f", gs->zrange_nz, Longdim);
02309 
02310         while (gs->zrange_nz * guess / Longdim >= .25) {
02311             guess *= .1;
02312 
02313             G_debug(3, "GS_get_exag_guess(): %f", guess);
02314         }
02315 
02316         while (gs->zrange_nz * guess / Longdim < .025) {
02317             guess *= 10.;
02318 
02319             G_debug(3, "GS_get_exag_guess(): %f", guess);
02320         }
02321 
02322         *exag = guess;
02323 
02324         return (1);
02325     }
02326 
02327     return (-1);
02328 }
02329 
02338 void GS_get_zrange_nz(float *min, float *max)
02339 {
02340     int i, first = 1;
02341     geosurf *gs;
02342 
02343     for (i = 0; i < Next_surf; i++) {
02344         if ((gs = gs_get_surf(Surf_ID[i]))) {
02345             if (first) {
02346                 first = 0;
02347                 *min = gs->zmin_nz;
02348                 *max = gs->zmax_nz;
02349             }
02350 
02351             if (gs->zmin_nz < *min) {
02352                 *min = gs->zmin_nz;
02353             }
02354 
02355             if (gs->zmax_nz > *max) {
02356                 *max = gs->zmax_nz;
02357             }
02358         }
02359     }
02360 
02361     G_debug(3, "GS_get_zrange_nz(): min=%g max=%g", *min, *max);
02362 
02363     return;
02364 }
02365 
02372 void GS_set_trans(int id, float xtrans, float ytrans, float ztrans)
02373 {
02374     geosurf *gs;
02375 
02376     G_debug(3, "GS_set_trans");
02377 
02378     gs = gs_get_surf(id);
02379 
02380     if (gs) {
02381         gs->x_trans = xtrans;
02382         gs->y_trans = ytrans;
02383         gs->z_trans = ztrans;
02384     }
02385 
02386     return;
02387 }
02388 
02395 void GS_get_trans(int id, float *xtrans, float *ytrans, float *ztrans)
02396 {
02397     geosurf *gs;
02398 
02399     G_debug(3, "GS_get_trans");
02400 
02401     gs = gs_get_surf(id);
02402 
02403     if (gs) {
02404         *xtrans = gs->x_trans;
02405         *ytrans = gs->y_trans;
02406         *ztrans = gs->z_trans;
02407     }
02408 
02409     return;
02410 }
02411 
02412 
02418 unsigned int GS_default_draw_color(void)
02419 {
02420 
02421     G_debug(3, "GS_default_draw_color");
02422 
02423     return ((unsigned int)Gd.bgcol);
02424 }
02425 
02431 unsigned int GS_background_color(void)
02432 {
02433     return ((unsigned int)Gd.bgcol);
02434 }
02435 
02441 void GS_set_draw(int where)
02442 {
02443     Buffermode = where;
02444 
02445     switch (where) {
02446     case GSD_BOTH:
02447         gsd_frontbuffer(1);
02448         gsd_backbuffer(1);
02449 
02450         break;
02451     case GSD_FRONT:
02452         gsd_frontbuffer(1);
02453         gsd_backbuffer(0);
02454 
02455         break;
02456     case GSD_BACK:
02457     default:
02458         gsd_frontbuffer(0);
02459         gsd_backbuffer(1);
02460 
02461         break;
02462     }
02463 
02464     return;
02465 }
02466 
02467 /*
02468    \brief Ready to draw
02469  */
02470 void GS_ready_draw(void)
02471 {
02472 
02473     G_debug(3, "GS_ready_draw");
02474 
02475     gsd_set_view(&Gv, &Gd);
02476 
02477     return;
02478 }
02479 
02483 void GS_done_draw(void)
02484 {
02485 
02486     G_debug(3, "GS_done_draw");
02487 
02488     if (GSD_BACK == Buffermode) {
02489         gsd_swapbuffers();
02490     }
02491 
02492     gsd_flush();
02493 
02494     return;
02495 }
02496 
02502 void GS_set_focus(float *realto)
02503 {
02504 
02505     G_debug(3, "GS_set_focus(): %f,%f,%f", realto[0], realto[1], realto[2]);
02506 
02507     Gv.infocus = 1;
02508     GS_v3eq(Gv.real_to, realto);
02509 
02510     gsd_set_view(&Gv, &Gd);
02511 
02512     return;
02513 }
02514 
02520 void GS_set_focus_real(float *realto)
02521 {
02522 
02523     G_get_set_window(&wind);
02524     realto[X] = realto[X] - wind.west - (wind.ew_res / 2.);
02525     realto[Y] = realto[Y] - wind.south - (wind.ns_res / 2.);
02526 
02527     Gv.infocus = 1;
02528     GS_v3eq(Gv.real_to, realto);
02529 
02530     gsd_set_view(&Gv, &Gd);
02531 
02532     return;
02533 }
02534 
02535 
02545 int GS_get_focus(float *realto)
02546 {
02547 
02548     G_debug(3, "GS_get_focus");
02549 
02550     if (Gv.infocus) {
02551         if (realto) {
02552             GS_v3eq(realto, Gv.real_to);
02553         }
02554     }
02555 
02556     return (Gv.infocus);
02557 }
02558 
02564 void GS_set_focus_center_map(int id)
02565 {
02566     float center[3];
02567     geosurf *gs;
02568 
02569     G_debug(3, "GS_set_focus_center_map");
02570 
02571     gs = gs_get_surf(id);
02572 
02573     if (gs) {
02574         center[X] = (gs->xmax - gs->xmin) / 2.;
02575         center[Y] = (gs->ymax - gs->ymin) / 2.;
02576         center[Z] = (gs->zmax_nz + gs->zmin_nz) / 2.;
02577 
02578         /* not yet working
02579            buff = gs_get_att_typbuff(gs, ATT_TOPO, 0);
02580            offset = gs->rows*gs->cols/2 + gs->cols/2;
02581            if (buff)
02582            {
02583            if (GET_MAPATT(buff, offset, tmp))
02584            {
02585            center[Z] = tmp;
02586            }
02587            }
02588          */
02589 
02590         GS_set_focus(center);
02591     }
02592 }
02593 
02599 void GS_moveto(float *pt)
02600 {
02601     float ft[3];
02602 
02603     G_debug(3, "GS_moveto(): %f,%f,%f", pt[0], pt[1], pt[2]);
02604 
02605     if (Gv.infocus) {
02606         GS_v3eq(Gv.from_to[FROM], pt);
02607         /*
02608            GS_v3eq(Gv.from_to[TO], Gv.real_to);
02609          */
02610         GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]);
02611         /* update inclination, look_dir if we're keeping these */
02612     }
02613     else {
02614         GS_v3eq(ft, Gv.from_to[TO]);
02615         GS_v3sub(ft, Gv.from_to[FROM]);
02616         GS_v3eq(Gv.from_to[FROM], pt);
02617         GS_v3eq(Gv.from_to[TO], pt);
02618         GS_v3add(Gv.from_to[TO], ft);
02619     }
02620 
02621     return;
02622 }
02623 
02629 void GS_moveto_real(float *pt)
02630 {
02631     gsd_real2model(pt);
02632     GS_moveto(pt);
02633 
02634     return;
02635 }
02636 
02648 int GS_get_zextents(int id, float *min, float *max, float *mid)
02649 {
02650     geosurf *gs;
02651 
02652     if (NULL == (gs = gs_get_surf(id))) {
02653         return (-1);
02654     }
02655 
02656     G_debug(3, "GS_get_zextents(): id=%d", id);
02657 
02658     return (gs_get_zextents(gs, min, max, mid));
02659 }
02660 
02671 int GS_get_zrange(float *min, float *max, int doexag)
02672 {
02673     int ret_surf, ret_vol;
02674     float surf_min, surf_max;
02675     float vol_min, vol_max;
02676 
02677     ret_surf = gs_get_zrange(&surf_min, &surf_max);
02678     ret_vol = gvl_get_zrange(&vol_min, &vol_max);
02679 
02680     if (ret_surf > 0 && ret_vol > 0) {
02681         *min = (surf_min < vol_min) ? surf_min : vol_min;
02682         *max = (surf_max < vol_max) ? surf_max : vol_max;
02683     }
02684     else if (ret_surf > 0) {
02685         *min = surf_min;
02686         *max = surf_max;
02687     }
02688     else if (ret_vol > 0) {
02689         *min = vol_min;
02690         *max = vol_max;
02691     }
02692 
02693     if (doexag) {
02694         *min *= Gv.vert_exag;
02695         *max *= Gv.vert_exag;
02696     }
02697 
02698     G_debug(3, "GS_get_zrange(): min=%g max=%g", *min, *max);
02699     return ((ret_surf > 0 || ret_vol > 0) ? (1) : (-1));
02700 }
02701 
02707 void GS_get_from(float *fr)
02708 {
02709     GS_v3eq(fr, Gv.from_to[FROM]);
02710 
02711     G_debug(3, "GS_get_from(): %f,%f,%f", fr[0], fr[1], fr[2]);
02712 
02713     return;
02714 }
02715 
02721 void GS_get_from_real(float *fr)
02722 {
02723     GS_v3eq(fr, Gv.from_to[FROM]);
02724     gsd_model2real(fr);
02725 
02726     return;
02727 }
02728 
02734 void GS_get_to_real(float *to)
02735 {
02736     float realto[3];
02737 
02738     G_get_set_window(&wind);
02739     GS_get_focus(realto);
02740     to[X] = realto[X] + wind.west + (wind.ew_res / 2.);
02741     to[Y] = realto[Y] + wind.south + (wind.ns_res / 2.);
02742     to[Z] = realto[Z];
02743 
02744     return;
02745 }
02746 
02747 
02754 void GS_zoom_setup(int *a, int *b, int *c, int *d, int *maxx, int *maxy)
02755 {
02756     GLint tmp[4];
02757     GLint num[2];
02758 
02759     gsd_getViewport(tmp, num);
02760     *a = tmp[0];
02761     *b = tmp[1];
02762     *c = tmp[2];
02763     *d = tmp[3];
02764     *maxx = num[0];
02765     *maxy = num[1];
02766 
02767     return;
02768 }
02769 
02777 void GS_get_to(float *to)
02778 {
02779     G_debug(3, "GS_get_to");
02780 
02781     GS_v3eq(to, Gv.from_to[TO]);
02782 
02783     return;
02784 }
02785 
02791 void GS_get_viewdir(float *dir)
02792 {
02793     GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir);
02794 
02795     return;
02796 }
02797 
02805 void GS_set_viewdir(float *dir)
02806 {
02807     float tmp[3];
02808 
02809     GS_v3eq(tmp, dir);
02810     GS_v3norm(tmp);
02811     GS_v3eq(Gv.from_to[TO], Gv.from_to[FROM]);
02812     GS_v3add(Gv.from_to[TO], tmp);
02813 
02814     GS_set_nofocus();
02815     gsd_set_view(&Gv, &Gd);
02816 
02817     return;
02818 }
02819 
02825 void GS_set_fov(int fov)
02826 {
02827     Gv.fov = fov;
02828 
02829     return;
02830 }
02831 
02837 int GS_get_fov(void)
02838 {
02839     return (Gv.fov);
02840 }
02841 
02847 int GS_get_twist(void)
02848 {
02849     return (Gv.twist);
02850 }
02851 
02859 void GS_set_twist(int t)
02860 {
02861     Gv.twist = t;
02862 
02863     return;
02864 }
02865 
02869 void GS_set_nofocus(void)
02870 {
02871     G_debug(3, "GS_set_nofocus");
02872 
02873     Gv.infocus = 0;
02874 
02875     return;
02876 }
02877 
02883 void GS_set_infocus(void)
02884 {
02885     G_debug(3, "GS_set_infocus");
02886 
02887     Gv.infocus = 1;
02888 
02889     return;
02890 }
02891 
02897 void GS_set_viewport(int left, int right, int bottom, int top)
02898 {
02899     G_debug(3, "GS_set_viewport(): left=%d, right=%d, "
02900             "bottom=%d, top=%d", left, right, bottom, top);
02901 
02902     gsd_viewport(left, right, bottom, top);
02903 
02904     return;
02905 }
02906 
02921 int GS_look_here(int sx, int sy)
02922 {
02923     float x, y, z, len, los[2][3];
02924     Point3 realto, dir;
02925     int id;
02926     geosurf *gs;
02927 
02928     if (GS_get_selected_point_on_surface(sx, sy, &id, &x, &y, &z)) {
02929         gs = gs_get_surf(id);
02930         if (gs) {
02931             realto[X] = x - gs->ox + gs->x_trans;
02932             realto[Y] = y - gs->oy + gs->y_trans;
02933             realto[Z] = z + gs->z_trans;
02934             GS_set_focus(realto);
02935 
02936             return (1);
02937         }
02938     }
02939     else {
02940         if (gsd_get_los(los, (short)sx, (short)sy)) {
02941             len = GS_distance(Gv.from_to[FROM], Gv.real_to);
02942             GS_v3dir(los[FROM], los[TO], dir);
02943             GS_v3mult(dir, len);
02944             realto[X] = Gv.from_to[FROM][X] + dir[X];
02945             realto[Y] = Gv.from_to[FROM][Y] + dir[Y];
02946             realto[Z] = Gv.from_to[FROM][Z] + dir[Z];
02947             GS_set_focus(realto);
02948 
02949             return (1);
02950         }
02951     }
02952 
02953     return (0);
02954 }
02955 
02970 int GS_get_selected_point_on_surface(int sx, int sy, int *id, float *x,
02971                                      float *y, float *z)
02972 {
02973     float los[2][3], find_dist[MAX_SURFS], closest;
02974     Point3 point, tmp, finds[MAX_SURFS];
02975     int surfs[MAX_SURFS], i, iclose, numhits = 0;
02976     geosurf *gs;
02977 
02978     /* returns surface-world coords */
02979     gsd_get_los(los, (short)sx, (short)sy);
02980 
02981     if (!gs_setlos_enterdata(los)) {
02982         G_debug(3, "gs_setlos_enterdata(los): returns false");
02983         return (0);
02984     }
02985 
02986     for (i = 0; i < Next_surf; i++) {
02987         G_debug(3, "id=%d", i);
02988 
02989         gs = gs_get_surf(Surf_ID[i]);
02990 
02991         /* los_intersect expects surf-world coords (xy transl, no scaling) */
02992 
02993 #if NVIZ_HACK
02994         if (gs_los_intersect1(Surf_ID[i], los, point)) {
02995 #else
02996         if (gs_los_intersect(Surf_ID[i], los, point)) {
02997 #endif
02998             if (!gs_point_is_masked(gs, point)) {
02999                 GS_v3eq(tmp, point);
03000                 tmp[X] += gs->x_trans;
03001                 tmp[Y] += gs->y_trans;
03002                 tmp[Z] += gs->z_trans;
03003                 find_dist[numhits] = GS_distance(los[FROM], tmp);
03004                 gsd_surf2real(gs, point);
03005                 GS_v3eq(finds[numhits], point);
03006                 surfs[numhits] = Surf_ID[i];
03007                 numhits++;
03008             }
03009         }
03010     }
03011 
03012     for (i = iclose = 0; i < numhits; i++) {
03013         closest = find_dist[iclose];
03014 
03015         if (find_dist[i] < closest) {
03016             iclose = i;
03017         }
03018     }
03019 
03020     if (numhits) {
03021         *x = finds[iclose][X];
03022         *y = finds[iclose][Y];
03023         *z = finds[iclose][Z];
03024         *id = surfs[iclose];
03025     }
03026 
03027     G_debug(3, "NumHits %d, next %d", numhits, Next_surf);
03028 
03029     return (numhits);
03030 }
03031 
03038 void GS_set_cplane_rot(int num, float dx, float dy, float dz)
03039 {
03040     gsd_cplane_setrot(num, dx, dy, dz);
03041 
03042     return;
03043 }
03044 
03051 void GS_set_cplane_trans(int num, float dx, float dy, float dz)
03052 {
03053     gsd_cplane_settrans(num, dx, dy, dz);
03054 
03055     return;
03056 }
03057 
03058 
03064 void GS_draw_cplane(int num)
03065 {
03066     geosurf *gsurfs[MAX_SURFS];
03067     int nsurfs;
03068 
03069     nsurfs = gs_num_surfaces();
03070     if (2 == nsurfs) {
03071         /* testing */
03072         gs_getall_surfaces(gsurfs);
03073         gsd_draw_cplane_fence(gsurfs[0], gsurfs[1], num);
03074     }
03075     else {
03076         gsd_draw_cplane(num);
03077     }
03078 
03079     return;
03080 }
03081 
03091 int GS_draw_cplane_fence(int hs1, int hs2, int num)
03092 {
03093     geosurf *gs1, *gs2;
03094 
03095     if (NULL == (gs1 = gs_get_surf(hs1))) {
03096         return (0);
03097     }
03098 
03099     if (NULL == (gs2 = gs_get_surf(hs2))) {
03100         return (0);
03101     }
03102 
03103     gsd_draw_cplane_fence(gs1, gs2, num);
03104 
03105     return (1);
03106 }
03107 
03111 void GS_alldraw_cplane_fences(void)
03112 {
03113     int onstate[MAX_CPLANES], i;
03114 
03115     gsd_get_cplanes_state(onstate);
03116 
03117     for (i = 0; i < MAX_CPLANES; i++) {
03118         if (onstate[i]) {
03119             GS_draw_cplane_fence(Surf_ID[0], Surf_ID[1], i);
03120         }
03121     }
03122 
03123     return;
03124 }
03125 
03131 void GS_set_cplane(int num)
03132 {
03133     gsd_cplane_on(num);
03134 
03135     return;
03136 }
03137 
03143 void GS_unset_cplane(int num)
03144 {
03145     gsd_cplane_off(num);
03146 
03147     return;
03148 }
03149 
03156 void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
03157 {
03158     float zexag;
03159 
03160     zexag = doexag ? Gv.vert_exag : 1.;
03161     *sx = *sy = Gv.scale;
03162     *sz = Gv.scale * zexag;
03163 
03164     return;
03165 }
03166 
03172 void GS_set_fencecolor(int mode)
03173 {
03174     gsd_setfc(mode);
03175 
03176     return;
03177 }
03178 
03184 int GS_get_fencecolor(void)
03185 {
03186     return gsd_getfc();
03187 }
03188 
03201 int GS_get_distance_alongsurf(int hs, float x1, float y1, float x2, float y2,
03202                               float *dist, int use_exag)
03203 {
03204     geosurf *gs;
03205     float p1[2], p2[2];
03206     
03207     gs = gs_get_surf(hs);
03208     if (gs == NULL) {
03209         return 0;
03210     }
03211     
03212     p1[X] = x1;
03213     p1[Y] = y1;
03214     p2[X] = x2;
03215     p2[Y] = y2;
03216     gsd_real2surf(gs, p1);
03217     gsd_real2surf(gs, p2);
03218 
03219     G_debug(3, "GS_get_distance_alongsurf(): hs=%d p1=%f,%f p2=%f,%f",
03220             hs, x1, y1, x2, y2);
03221     return gs_distance_onsurf(gs, p1, p2, dist, use_exag);
03222 }
03223 
03232 int GS_save_3dview(const char *vname, int surfid)
03233 {
03234     return (Gs_save_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid)));
03235 }
03236 
03245 int GS_load_3dview(const char *vname, int surfid)
03246 {
03247 
03248     return (Gs_load_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid)));
03249 
03250     /* what to do about lights - I guess, delete all &
03251        create any that exist in 3dview file */
03252 }
03253 
03254 /************************************************************************
03255 * Following routines use Graphics Library
03256 ************************************************************************/
03257 
03263 void GS_init_view(void)
03264 {
03265     static int first = 1;
03266 
03267     G_debug(3, "GS_init_view");
03268 
03269     if (first) {
03270         first = 0;
03271         glMatrixMode(GL_MODELVIEW);
03272 
03273         /* OGLXXX doublebuffer: use GLX_DOUBLEBUFFER in attriblist */
03274         /* glxChooseVisual(*dpy, screen, *attriblist); */
03275         /* OGLXXX
03276          * ZMIN not needed -- always 0.
03277          * ZMAX not needed -- always 1.
03278          * getgdesc other posiblilties:
03279          *      glxGetConfig();
03280          *      glxGetCurrentContext();
03281          *      glxGetCurrentDrawable();
03282          * GLint gdtmp;
03283          * getgdesc other posiblilties:
03284          *      glxGetConfig();
03285          *      glxGetCurrentContext();
03286          *      glxGetCurrentDrawable();
03287          * GLint gdtmp;
03288          * glDepthRange params must be scaled to [0, 1]
03289          */
03290         glDepthRange(0.0, 1.0);
03291         glEnable(GL_DEPTH_TEST);
03292         glDepthFunc(GL_LEQUAL);
03293         /* } */
03294 
03295         /* replace these with something meaningful */
03296         Gv.fov = 450;
03297         Gv.twist = 0;
03298         Gv.from_to[FROM][X] = Gv.from_to[FROM][Y] =
03299             Gv.from_to[FROM][Z] = GS_UNIT_SIZE / 2.;
03300 
03301         Gv.from_to[TO][X] = GS_UNIT_SIZE / 2.;
03302         Gv.from_to[TO][Y] = GS_UNIT_SIZE / 2.;
03303         Gv.from_to[TO][Z] = 0.;
03304         Gv.from_to[TO][W] = Gv.from_to[FROM][W] = 1.;
03305 
03306         Gv.real_to[W] = 1.;
03307         Gv.vert_exag = 1.;
03308 
03309         GS_v3eq(Gv.real_to, Gv.from_to[TO]);
03310         GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]);
03311 
03312         /*
03313            Gd.nearclip = 50;
03314            Gd.farclip = 10000.;
03315          */
03316         Gd.nearclip = 10.;
03317         Gd.farclip = 10000.;
03318         Gd.aspect = (float)GS_get_aspect();
03319 
03320         GS_set_focus(Gv.real_to);
03321     }
03322 
03323     return;
03324 }
03325 
03331 void GS_clear(int col)
03332 {
03333     G_debug(3, "GS_clear");
03334 
03335     col = col | 0xFF000000;
03336 
03337     /* OGLXXX
03338      * change glClearDepth parameter to be in [0, 1]
03339      * ZMAX not needed -- always 1.
03340      * getgdesc other posiblilties:
03341      *      glxGetConfig();
03342      *      glxGetCurrentContext();
03343      *      glxGetCurrentDrawable();
03344      * GLint gdtmp;
03345      */
03346     glClearDepth(1.0);
03347     glClearColor(((float)((col) & 0xff)) / 255.,
03348                  (float)((col) >> 8 & 0xff) / 255.,
03349                  (float)((col) >> 16 & 0xff) / 255.,
03350                  (float)((col) >> 24 & 0xff) / 255.);
03351     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
03352 
03353     Gd.bgcol = col;
03354     Modelshowing = 0;
03355     gsd_flush();
03356 
03357     return;
03358 }
03359 
03365 double GS_get_aspect(void)
03366 {
03367     int left, right, bottom, top;
03368     GLint tmp[4];
03369 
03370     /* OGLXXX
03371      * get GL_VIEWPORT:
03372      * You can probably do better than this.
03373      */
03374     glGetIntegerv(GL_VIEWPORT, tmp);
03375     left = tmp[0];
03376     right = tmp[0] + tmp[2] - 1;
03377     bottom = tmp[1];
03378     top = tmp[1] + tmp[3] - 1;
03379 
03380     G_debug(3, "GS_get_aspect(): left=%d, right=%d, top=%d, bottom=%d",
03381             left, right, top, bottom);
03382 
03383     return ((double)(right - left) / (top - bottom));
03384 }
03385 
03393 int GS_has_transparency(void)
03394 {
03395     /* OGLXXX
03396      * getgdesc other posiblilties:
03397      *      glxGetConfig();
03398      *      glxGetCurrentContext();
03399      *      glxGetCurrentDrawable();
03400      * GLint gdtmp;
03401      * blending is ALWAYS supported.
03402      * This function returns whether it is enabled.
03403      * return((glGetIntegerv(GL_BLEND, &gdtmp), gdtmp));
03404      */
03405 
03406     return (1);
03407 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines