|
GRASS Programmer's Manual
6.5.svn(2012)-r51648
|
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 Resetlight = 1; 00082 static int Modelshowing = 0; 00083 00084 void void_func(void) 00085 { 00086 return; 00087 } 00088 00096 void GS_libinit(void) 00097 { 00098 static int first = 1; 00099 00100 G_get_set_window(&wind); 00101 00102 Region[0] = wind.north; 00103 Region[1] = wind.south; 00104 Region[2] = wind.west; 00105 Region[3] = wind.east; 00106 00107 /* scale largest dimension to GS_UNIT_SIZE */ 00108 if ((wind.east - wind.west) > (wind.north - wind.south)) { 00109 Longdim = (wind.east - wind.west); 00110 } 00111 else { 00112 Longdim = (wind.north - wind.south); 00113 } 00114 00115 Gv.scale = GS_UNIT_SIZE / Longdim; 00116 00117 G_debug(1, "GS_libinit(): n=%f s=%f w=%f e=%f scale=%f first=%d", 00118 Region[0], Region[1], Region[2], Region[3], Gv.scale, first); 00119 00120 Cxl_func = void_func; 00121 Swap_func = void_func; 00122 00123 00124 if (first) { 00125 gs_init(); 00126 } 00127 00128 first = 0; 00129 00130 return; 00131 } 00132 00140 int GS_get_longdim(float *dim) 00141 { 00142 *dim = Longdim; 00143 00144 G_debug(3, "GS_get_longdim(): dim=%g", *dim); 00145 00146 return (1); 00147 } 00148 00156 int GS_get_region(float *n, float *s, float *w, float *e) 00157 { 00158 *n = Region[0]; 00159 *s = Region[1]; 00160 *w = Region[2]; 00161 *e = Region[3]; 00162 00163 return (1); 00164 } 00165 00172 void GS_set_att_defaults(float *defs, float *null_defs) 00173 { 00174 int i; 00175 00176 G_debug(3, "GS_set_att_defaults"); 00177 00178 for (i = 0; i < MAX_ATTS; i++) { 00179 Default_const[i] = defs[i]; 00180 Default_nulls[i] = null_defs[i]; 00181 } 00182 00183 return; 00184 } 00185 00194 int GS_surf_exists(int id) 00195 { 00196 int i, found = 0; 00197 00198 G_debug(3, "GS_surf_exists(): id=%d", id); 00199 00200 00201 if (NULL == gs_get_surf(id)) { 00202 return (0); 00203 } 00204 00205 for (i = 0; i < Next_surf && !found; i++) { 00206 if (Surf_ID[i] == id) { 00207 found = 1; 00208 } 00209 } 00210 00211 return (found); 00212 } 00213 00224 int GS_new_surface(void) 00225 { 00226 geosurf *ns; 00227 00228 G_debug(3, "GS_new_surface():"); 00229 00230 if (Next_surf < MAX_SURFS) { 00231 ns = gs_get_new_surface(); 00232 gs_init_surf(ns, wind.west + wind.ew_res / 2., 00233 wind.south + wind.ns_res / 2., wind.rows, wind.cols, 00234 wind.ew_res, wind.ns_res); 00235 gs_set_defaults(ns, Default_const, Default_nulls); 00236 00237 /* make default shine current */ 00238 gs_set_att_src(ns, ATT_SHINE, CONST_ATT); 00239 00240 Surf_ID[Next_surf] = ns->gsurf_id; 00241 ++Next_surf; 00242 00243 G_debug(3, " id=%d", ns->gsurf_id); 00244 00245 return (ns->gsurf_id); 00246 } 00247 00248 00249 00250 return (-1); 00251 } 00252 void GS_set_light_reset(int i) 00253 { 00254 Resetlight = i; 00255 if (i) 00256 Numlights = 0; 00257 } 00258 int GS_get_light_reset(void) 00259 { 00260 return Resetlight; 00261 } 00268 int GS_new_light(void) 00269 { 00270 int i; 00271 00272 if (GS_get_light_reset()) { 00273 00274 GS_set_light_reset(0); 00275 00276 for (i = 0; i < MAX_LIGHTS; i++) { 00277 Gv.lights[i].position[X] = Gv.lights[i].position[Y] = 0.0; 00278 Gv.lights[i].position[Z] = 1.0; 00279 Gv.lights[i].position[W] = 0.0; /* infinite */ 00280 Gv.lights[i].color[0] = Gv.lights[i].color[1] = 00281 Gv.lights[i].color[2] = 1.0; 00282 Gv.lights[i].ambient[0] = Gv.lights[i].ambient[1] = 00283 Gv.lights[i].ambient[2] = 0.2; 00284 Gv.lights[i].shine = 32.0; 00285 } 00286 00287 gsd_init_lightmodel(); 00288 } 00289 00290 if (Numlights < MAX_LIGHTS) { 00291 gsd_deflight(Numlights + 1, &(Gv.lights[Numlights])); 00292 gsd_switchlight(Numlights + 1, 1); 00293 00294 return ++Numlights; 00295 } 00296 00297 return -1; 00298 } 00299 00309 void GS_setlight_position(int num, float xpos, float ypos, float zpos, 00310 int local) 00311 { 00312 if (num) { 00313 num -= 1; 00314 if (num < Numlights) { 00315 Gv.lights[num].position[X] = xpos; 00316 Gv.lights[num].position[Y] = ypos; 00317 Gv.lights[num].position[Z] = zpos; 00318 Gv.lights[num].position[W] = (float)local; 00319 00320 gsd_deflight(num + 1, &(Gv.lights[num])); 00321 } 00322 } 00323 00324 return; 00325 } 00326 00327 00335 void GS_getlight_position(int num, float *xpos, float *ypos, float *zpos, 00336 int *local) 00337 { 00338 if (num) { 00339 num -= 1; 00340 if (num < Numlights) { 00341 *xpos = Gv.lights[num].position[X]; 00342 *ypos = Gv.lights[num].position[Y]; 00343 *zpos = Gv.lights[num].position[Z]; 00344 *local = (int)Gv.lights[num].position[W]; 00345 00346 } 00347 } 00348 00349 return; 00350 } 00351 00358 void GS_setlight_color(int num, float red, float green, float blue) 00359 { 00360 if (num) { 00361 num -= 1; 00362 if (num < Numlights) { 00363 Gv.lights[num].color[0] = red; 00364 Gv.lights[num].color[1] = green; 00365 Gv.lights[num].color[2] = blue; 00366 00367 gsd_deflight(num + 1, &(Gv.lights[num])); 00368 } 00369 } 00370 00371 return; 00372 } 00373 00380 void GS_getlight_color(int num, float *red, float *green, float *blue) 00381 { 00382 if (num) { 00383 num -= 1; 00384 if (num < Numlights) { 00385 *red = Gv.lights[num].color[0]; 00386 *green = Gv.lights[num].color[1]; 00387 *blue = Gv.lights[num].color[2]; 00388 } 00389 } 00390 00391 return; 00392 } 00393 00402 void GS_setlight_ambient(int num, float red, float green, float blue) 00403 { 00404 if (num) { 00405 num -= 1; 00406 if (num < Numlights) { 00407 Gv.lights[num].ambient[0] = red; 00408 Gv.lights[num].ambient[1] = green; 00409 Gv.lights[num].ambient[2] = blue; 00410 00411 gsd_deflight(num + 1, &(Gv.lights[num])); 00412 } 00413 } 00414 00415 return; 00416 } 00417 00424 void GS_getlight_ambient(int num, float *red, float *green, float *blue) 00425 { 00426 if (num) { 00427 num -= 1; 00428 if (num < Numlights) { 00429 *red = Gv.lights[num].ambient[0]; 00430 *green = Gv.lights[num].ambient[1]; 00431 *blue = Gv.lights[num].ambient[2]; 00432 } 00433 } 00434 00435 return; 00436 } 00437 00438 00442 void GS_lights_off(void) 00443 { 00444 int i; 00445 00446 for (i = 0; i < Numlights; i++) { 00447 gsd_switchlight(i + 1, 0); 00448 } 00449 00450 return; 00451 } 00452 00456 void GS_lights_on(void) 00457 { 00458 int i; 00459 00460 for (i = 0; i < Numlights; i++) { 00461 gsd_switchlight(i + 1, 1); 00462 } 00463 00464 return; 00465 } 00466 00473 void GS_switchlight(int num, int on) 00474 { 00475 if (num) { 00476 num -= 1; 00477 00478 if (num < Numlights) { 00479 gsd_switchlight(num + 1, on); 00480 } 00481 } 00482 00483 return; 00484 } 00485 00492 int GS_transp_is_set(void) 00493 { 00494 return (gs_att_is_set(NULL, ATT_TRANSP) || (FC_GREY == gsd_getfc())); 00495 } 00496 00502 void GS_get_modelposition1(float pos[]) 00503 { 00504 /* TODO: Still needs work to handle other cases */ 00505 /* this is a quick hack to get lighting adjustments debugged */ 00506 /* 00507 GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], center); 00508 GS_v3mult(center, 1000); 00509 GS_v3add(center, Gv.from_to[FROM]); 00510 */ 00511 00512 gs_get_datacenter(pos); 00513 gs_get_data_avg_zmax(&(pos[Z])); 00514 00515 G_debug(1, "GS_get_modelposition1(): model position: %f %f %f", 00516 pos[X], pos[Y], pos[Z]); 00517 00518 return; 00519 } 00520 00531 void GS_get_modelposition(float *siz, float *pos) 00532 { 00533 float dist, near_h, dir[3]; 00534 00535 dist = 2. * Gd.nearclip; 00536 00537 near_h = 2.0 * tan(4.0 * atan(1.) * Gv.fov / 3600.) * dist; 00538 *siz = near_h / 8.0; 00539 00540 /* prevent clipping - would only happen if fov > ~127 degrees, at 00541 fov = 2.0 * atan(2.0) */ 00542 00543 if (*siz > Gd.nearclip) { 00544 *siz = Gd.nearclip; 00545 } 00546 00547 GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir); 00548 00549 pos[X] = Gv.from_to[FROM][X] + dir[X] * dist; 00550 pos[Y] = Gv.from_to[FROM][Y] + dir[Y] * dist; 00551 pos[Z] = Gv.from_to[FROM][Z] + dir[Z] * dist; 00552 00553 return; 00554 } 00555 00556 00568 void GS_set_Narrow(int *pt, int id, float *pos2) 00569 { 00570 geosurf *gs; 00571 float x, y, z; 00572 GLdouble modelMatrix[16], projMatrix[16]; 00573 GLint viewport[4]; 00574 00575 if (GS_get_selected_point_on_surface(pt[X], pt[Y], &id, &x, &y, &z)) { 00576 gs = gs_get_surf(id); 00577 if (gs) { 00578 z = gs->zmax; 00579 pos2[X] = (float)x - gs->ox + gs->x_trans; 00580 pos2[Y] = (float)y - gs->oy + gs->y_trans; 00581 pos2[Z] = (float)z + gs->z_trans; 00582 00583 return; 00584 } 00585 } 00586 else { 00587 gs = gs_get_surf(id); 00588 00589 /* Need to get model matrix, etc 00590 * to run gluUnProject 00591 */ 00592 gsd_pushmatrix(); 00593 gsd_do_scale(1); 00594 glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); 00595 glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); 00596 glGetIntegerv(GL_VIEWPORT, viewport); 00597 00598 if (gs) { 00599 GLdouble out_near[3], out_far[3]; 00600 GLdouble factor; 00601 GLdouble out[3]; 00602 00603 z = (float)gs->zmax + gs->z_trans; 00604 00605 gluUnProject((GLdouble) pt[X], (GLdouble) pt[Y], (GLdouble) 0., 00606 modelMatrix, projMatrix, viewport, 00607 &out_near[X], &out_near[Y], &out_near[Z]); 00608 gluUnProject((GLdouble) pt[X], (GLdouble) pt[Y], (GLdouble) 1., 00609 modelMatrix, projMatrix, viewport, 00610 &out_far[X], &out_far[Y], &out_far[Z]); 00611 00612 glPopMatrix(); 00613 00614 factor = (out_near[Z] - z) / (out_near[Z] - out_far[Z]); 00615 00616 out[X] = out_near[X] - ((out_near[X] - out_far[X]) * factor); 00617 out[Y] = out_near[Y] - ((out_near[Y] - out_far[Y]) * factor); 00618 out[Z] = z; 00619 00620 pos2[X] = (float)out[X]; 00621 pos2[Y] = (float)out[Y]; 00622 pos2[Z] = (float)out[Z]; 00623 00624 return; 00625 00626 } 00627 } 00628 return; 00629 } 00630 00637 void GS_draw_X(int id, float *pt) 00638 { 00639 geosurf *gs; 00640 Point3 pos; 00641 float siz; 00642 00643 if ((gs = gs_get_surf(id))) { 00644 GS_get_longdim(&siz); 00645 siz /= 200.; 00646 pos[X] = pt[X] - gs->ox; 00647 pos[Y] = pt[Y] - gs->oy; 00648 _viewcell_tri_interp(gs, pos); 00649 00650 gsd_pushmatrix(); 00651 00652 gsd_do_scale(1); 00653 gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans); 00654 gsd_linewidth(1); 00655 00656 if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) { 00657 pos[Z] = gs->att[ATT_TOPO].constant; 00658 gs = NULL; /* tells gpd_obj to use given Z val */ 00659 } 00660 00661 gpd_obj(gs, Gd.bgcol, siz, ST_GYRO, pos); 00662 gsd_flush(); 00663 00664 gsd_popmatrix(); 00665 } 00666 00667 return; 00668 } 00669 00676 void GS_draw_line_onsurf(int id, float x1, float y1, float x2, float y2) 00677 { 00678 float p1[2], p2[2]; 00679 geosurf *gs; 00680 00681 if ((gs = gs_get_surf(id))) { 00682 p1[X] = x1 - gs->ox; 00683 p1[Y] = y1 - gs->oy; 00684 p2[X] = x2 - gs->ox; 00685 p2[Y] = y2 - gs->oy; 00686 00687 gsd_pushmatrix(); 00688 00689 gsd_do_scale(1); 00690 gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans); 00691 gsd_linewidth(1); 00692 00693 gsd_color_func(GS_default_draw_color()); 00694 gsd_line_onsurf(gs, p1, p2); 00695 00696 gsd_popmatrix(); 00697 gsd_flush(); 00698 } 00699 00700 return; 00701 } 00702 00715 int GS_draw_nline_onsurf(int id, float x1, float y1, float x2, float y2, 00716 float *lasp, int n) 00717 { 00718 float p1[2], p2[2]; 00719 geosurf *gs; 00720 int ret = 0; 00721 00722 if ((gs = gs_get_surf(id))) { 00723 p1[X] = x1 - gs->ox; 00724 p1[Y] = y1 - gs->oy; 00725 p2[X] = x2 - gs->ox; 00726 p2[Y] = y2 - gs->oy; 00727 00728 gsd_pushmatrix(); 00729 00730 gsd_do_scale(1); 00731 gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans); 00732 gsd_linewidth(1); 00733 gsd_color_func(GS_default_draw_color()); 00734 ret = gsd_nline_onsurf(gs, p1, p2, lasp, n); 00735 gsd_surf2real(gs, lasp); 00736 00737 gsd_popmatrix(); 00738 gsd_flush(); 00739 } 00740 00741 return (ret); 00742 } 00743 00753 void GS_draw_flowline_at_xy(int id, float x, float y) 00754 { 00755 geosurf *gs; 00756 float nv[3], pdir[2], mult; 00757 float p1[2], p2[2], next[2]; 00758 int i = 0; 00759 00760 if ((gs = gs_get_surf(id))) { 00761 p1[X] = x; 00762 p1[Y] = y; 00763 /* multiply by 1.5 resolutions to ensure a crossing ? */ 00764 mult = .1 * (VXRES(gs) > VYRES(gs) ? VXRES(gs) : VYRES(gs)); 00765 00766 GS_coordpair_repeats(p1, p1, 50); 00767 00768 while (1 == GS_get_norm_at_xy(id, p1[X], p1[Y], nv)) { 00769 if (nv[Z] == 1.0) { 00770 if (pdir[X] == 0.0 && pdir[Y] == 0.0) { 00771 break; 00772 } 00773 00774 p2[X] = p1[X] + (pdir[X] * mult); 00775 p2[Y] = p1[Y] + (pdir[Y] * mult); 00776 } 00777 else { 00778 /* use previous direction */ 00779 GS_v2norm(nv); 00780 p2[X] = p1[X] + (nv[X] * mult); 00781 p2[Y] = p1[Y] + (nv[Y] * mult); 00782 pdir[X] = nv[X]; 00783 pdir[Y] = nv[Y]; 00784 } 00785 00786 if (i > 2000) { 00787 break; 00788 } 00789 00790 if (GS_coordpair_repeats(p1, p2, 0)) { 00791 break; 00792 } 00793 00794 /* Think about this: */ 00795 /* degenerate line means edge or level edge ? */ 00796 /* next is filled with last point drawn */ 00797 if (2 > GS_draw_nline_onsurf(id, p1[X], p1[Y], 00798 p2[X], p2[Y], next, 3)) { 00799 break; 00800 } 00801 00802 p1[X] = next[X]; 00803 p1[Y] = next[Y]; 00804 } 00805 00806 G_debug(3, "GS_draw_flowline_at_xy(): dir: %f %f", nv[X], nv[Y]); 00807 } 00808 00809 return; 00810 } 00811 00820 void GS_draw_fringe(int id, unsigned long clr, float elev, int *where) 00821 { 00822 geosurf *gs; 00823 00824 G_debug(3, "GS_draw_fringe(): id: %d clr: %ld elev %f edges: %d %d %d %d", 00825 id, clr, elev, where[0], where[1], where[2], where[3]); 00826 if ((gs = gs_get_surf(id))) 00827 gsd_display_fringe(gs, clr, elev, where); 00828 00829 } 00830 00831 00845 int GS_draw_legend(const char *name, GLuint fontbase, int size, int *flags, 00846 float *range, int *pt) 00847 { 00848 int list_no; 00849 00850 list_no = gsd_put_legend(name, fontbase, size, flags, range, pt); 00851 00852 return (list_no); 00853 } 00854 00863 void GS_draw_list(GLuint list_id) 00864 { 00865 gsd_calllist(list_id); 00866 glFlush(); 00867 return; 00868 } 00869 00876 void GS_draw_all_list(void) 00877 { 00878 gsd_calllists(0); /* not sure if 0 is right - MN */ 00879 glFlush(); 00880 return; 00881 } 00882 00888 void GS_delete_list(GLuint list_id) 00889 { 00890 gsd_deletelist(list_id, 1); 00891 00892 return; 00893 } 00894 00898 void GS_draw_lighting_model1(void) 00899 { 00900 static float center[3]; 00901 float tcenter[3]; 00902 00903 if (!Modelshowing) { 00904 GS_get_modelposition1(center); 00905 } 00906 00907 GS_v3eq(tcenter, center); 00908 00909 gsd_zwritemask(0x0); 00910 gsd_backface(1); 00911 00912 gsd_colormode(CM_AD); 00913 gsd_shademodel(DM_GOURAUD); 00914 gsd_pushmatrix(); 00915 gsd_do_scale(1); 00916 00917 if (Gv.vert_exag) { 00918 tcenter[Z] *= Gv.vert_exag; 00919 gsd_scale(1.0, 1.0, 1. / Gv.vert_exag); 00920 } 00921 00922 gsd_drawsphere(tcenter, 0xDDDDDD, (float)(Longdim / 10.)); 00923 gsd_popmatrix(); 00924 Modelshowing = 1; 00925 00926 gsd_backface(0); 00927 gsd_zwritemask(0xffffffff); 00928 00929 return; 00930 } 00931 00938 void GS_draw_lighting_model(void) 00939 { 00940 static float center[3], size; 00941 float tcenter[3], tsize; 00942 int i, wason[MAX_CPLANES]; 00943 00944 gsd_get_cplanes_state(wason); 00945 00946 for (i = 0; i < MAX_CPLANES; i++) { 00947 if (wason[i]) { 00948 gsd_cplane_off(i); 00949 } 00950 } 00951 00952 00953 if (!Modelshowing) { 00954 GS_get_modelposition(&size, center); 00955 } 00956 00957 GS_v3eq(tcenter, center); 00958 tsize = size; 00959 00960 gsd_zwritemask(0x0); 00961 gsd_backface(1); 00962 00963 gsd_colormode(CM_DIFFUSE); 00964 gsd_shademodel(DM_GOURAUD); 00965 gsd_pushmatrix(); 00966 gsd_drawsphere(tcenter, 0xDDDDDD, tsize); 00967 gsd_popmatrix(); 00968 Modelshowing = 1; 00969 00970 gsd_backface(0); 00971 gsd_zwritemask(0xffffffff); 00972 00973 for (i = 0; i < MAX_CPLANES; i++) { 00974 if (wason[i]) { 00975 gsd_cplane_on(i); 00976 } 00977 } 00978 00979 gsd_flush(); 00980 00981 return; 00982 } 00983 00994 int GS_update_curmask(int id) 00995 { 00996 geosurf *gs; 00997 00998 gs = gs_get_surf(id); 00999 return (gs_update_curmask(gs)); 01000 } 01001 01012 int GS_is_masked(int id, float *pt) 01013 { 01014 geosurf *gs; 01015 Point3 tmp; 01016 01017 if ((gs = gs_get_surf(id))) { 01018 tmp[X] = pt[X] - gs->ox; 01019 tmp[Y] = pt[Y] - gs->oy; 01020 01021 return (gs_point_is_masked(gs, tmp)); 01022 } 01023 01024 return (-1); 01025 } 01026 01030 void GS_unset_SDsurf(void) 01031 { 01032 gsdiff_set_SDref(NULL); 01033 SDref_surf = 0; 01034 01035 return; 01036 } 01037 01046 int GS_set_SDsurf(int id) 01047 { 01048 geosurf *gs; 01049 01050 if ((gs = gs_get_surf(id))) { 01051 gsdiff_set_SDref(gs); 01052 SDref_surf = id; 01053 01054 return (1); 01055 } 01056 01057 return (0); 01058 } 01059 01067 int GS_set_SDscale(float scale) 01068 { 01069 gsdiff_set_SDscale(scale); 01070 01071 return (1); 01072 } 01073 01082 int GS_get_SDsurf(int *id) 01083 { 01084 geosurf *gs; 01085 01086 if ((gs = gsdiff_get_SDref())) { 01087 *id = SDref_surf; 01088 01089 return (1); 01090 } 01091 01092 return (0); 01093 } 01094 01102 int GS_get_SDscale(float *scale) 01103 { 01104 *scale = gsdiff_get_SDscale(); 01105 01106 return (1); 01107 } 01108 01116 int GS_update_normals(int id) 01117 { 01118 geosurf *gs; 01119 01120 gs = gs_get_surf(id); 01121 01122 return (gs_calc_normals(gs)); 01123 } 01124 01137 int GS_get_att(int id, int att, int *set, float *constant, char *mapname) 01138 { 01139 int src; 01140 geosurf *gs; 01141 01142 gs = gs_get_surf(id); 01143 if (gs) { 01144 if (-1 != (src = gs_get_att_src(gs, att))) { 01145 *set = src; 01146 01147 if (src == CONST_ATT) { 01148 *constant = gs->att[att].constant; 01149 } 01150 else if (src == MAP_ATT) { 01151 strcpy(mapname, gsds_get_name(gs->att[att].hdata)); 01152 } 01153 01154 return (1); 01155 } 01156 01157 return (-1); 01158 } 01159 01160 return (-1); 01161 } 01162 01180 int GS_get_cat_at_xy(int id, int att, char *catstr, float x, float y) 01181 { 01182 int offset, drow, dcol, vrow, vcol; 01183 float ftmp, pt[3]; 01184 typbuff *buff; 01185 geosurf *gs; 01186 01187 *catstr = '\0'; 01188 gs = gs_get_surf(id); 01189 01190 if (NULL == gs) { 01191 return -1; 01192 } 01193 01194 pt[X] = x; 01195 pt[Y] = y; 01196 01197 gsd_real2surf(gs, pt); 01198 if (gs_point_is_masked(gs, pt)) { 01199 return -1; 01200 } 01201 01202 if (!in_vregion(gs, pt)) { 01203 return -1; 01204 } 01205 01206 if (MAP_ATT != gs_get_att_src(gs, att)) { 01207 sprintf(catstr, _("no category info")); 01208 return -1; 01209 } 01210 01211 buff = gs_get_att_typbuff(gs, att, 0); 01212 01213 vrow = Y2VROW(gs, pt[Y]); 01214 vcol = X2VCOL(gs, pt[X]); 01215 drow = VROW2DROW(gs, vrow); 01216 dcol = VCOL2DCOL(gs, vcol); 01217 01218 offset = DRC2OFF(gs, drow, dcol); 01219 01220 if (GET_MAPATT(buff, offset, ftmp)) { 01221 return 01222 (Gs_get_cat_label(gsds_get_name(gs->att[att].hdata), 01223 drow, dcol, catstr)); 01224 } 01225 01226 sprintf(catstr, _("no data")); 01227 01228 return 1; 01229 } 01230 01243 int GS_get_norm_at_xy(int id, float x, float y, float *nv) 01244 { 01245 int offset, drow, dcol, vrow, vcol; 01246 float pt[3]; 01247 geosurf *gs; 01248 01249 gs = gs_get_surf(id); 01250 01251 if (NULL == gs) { 01252 return (-1); 01253 } 01254 01255 if (gs->norm_needupdate) { 01256 gs_calc_normals(gs); 01257 } 01258 01259 pt[X] = x; 01260 pt[Y] = y; 01261 01262 gsd_real2surf(gs, pt); 01263 if (gs_point_is_masked(gs, pt)) { 01264 return (-1); 01265 } 01266 01267 if (!in_vregion(gs, pt)) { 01268 return (-1); 01269 } 01270 01271 vrow = Y2VROW(gs, pt[Y]); 01272 vcol = X2VCOL(gs, pt[X]); 01273 drow = VROW2DROW(gs, vrow); 01274 dcol = VCOL2DCOL(gs, vcol); 01275 01276 offset = DRC2OFF(gs, drow, dcol); 01277 01278 if (gs->norms) { 01279 FNORM(gs->norms[offset], nv); 01280 } 01281 else { 01282 /* otherwise must be a constant */ 01283 nv[0] = 0.0; 01284 nv[1] = 0.0; 01285 nv[2] = 1.0; 01286 } 01287 01288 return (1); 01289 } 01290 01307 int GS_get_val_at_xy(int id, int att, char *valstr, float x, float y) 01308 { 01309 int offset, drow, dcol, vrow, vcol; 01310 float ftmp, pt[3]; 01311 typbuff *buff; 01312 geosurf *gs; 01313 01314 *valstr = '\0'; 01315 gs = gs_get_surf(id); 01316 01317 if (NULL == gs) { 01318 return -1; 01319 } 01320 01321 pt[X] = x; 01322 pt[Y] = y; 01323 01324 gsd_real2surf(gs, pt); 01325 01326 if (gs_point_is_masked(gs, pt)) { 01327 return -1; 01328 } 01329 01330 if (!in_vregion(gs, pt)) { 01331 return (-1); 01332 } 01333 01334 if (CONST_ATT == gs_get_att_src(gs, att)) { 01335 if (att == ATT_COLOR) { 01336 int r, g, b, i; 01337 01338 i = gs->att[att].constant; 01339 sprintf(valstr, "R%d G%d B%d", 01340 INT_TO_RED(i, r), INT_TO_GRN(i, g), INT_TO_BLU(i, b)); 01341 } 01342 else { 01343 sprintf(valstr, "%f", gs->att[att].constant); 01344 } 01345 01346 return 1; 01347 } 01348 else if (MAP_ATT != gs_get_att_src(gs, att)) { 01349 return -1; 01350 } 01351 01352 buff = gs_get_att_typbuff(gs, att, 0); 01353 01354 vrow = Y2VROW(gs, pt[Y]); 01355 vcol = X2VCOL(gs, pt[X]); 01356 drow = VROW2DROW(gs, vrow); 01357 dcol = VCOL2DCOL(gs, vcol); 01358 01359 offset = DRC2OFF(gs, drow, dcol); 01360 01361 if (GET_MAPATT(buff, offset, ftmp)) { 01362 if (att == ATT_COLOR) { 01363 int r, g, b, i; 01364 01365 i = gs_mapcolor(gs_get_att_typbuff(gs, ATT_COLOR, 0), 01366 &(gs->att[ATT_COLOR]), offset); 01367 sprintf(valstr, "R%d G%d B%d", 01368 INT_TO_RED(i, r), INT_TO_GRN(i, g), INT_TO_BLU(i, b)); 01369 } 01370 else { 01371 sprintf(valstr, "%f", ftmp); 01372 } 01373 01374 return (1); 01375 } 01376 01377 sprintf(valstr, "NULL"); 01378 01379 return (1); 01380 } 01381 01390 int GS_unset_att(int id, int att) 01391 { 01392 geosurf *gs; 01393 01394 gs = gs_get_surf(id); 01395 gs->mask_needupdate = 1; 01396 01397 return (gs_set_att_src(gs, att, NOTSET_ATT)); 01398 } 01399 01409 int GS_set_att_const(int id, int att, float constant) 01410 { 01411 geosurf *gs; 01412 int ret; 01413 01414 gs = gs_get_surf(id); 01415 ret = (gs_set_att_const(gs, att, constant)); 01416 01417 Gs_update_attrange(gs, att); 01418 01419 return (ret); 01420 } 01421 01433 int GS_set_maskmode(int id, int mode) 01434 { 01435 geosurf *gs; 01436 01437 gs = gs_get_surf(id); 01438 01439 if (gs) { 01440 gs->att[ATT_MASK].constant = mode; 01441 gs->mask_needupdate = 1; 01442 01443 return (mode); 01444 } 01445 01446 return (-1); 01447 } 01448 01458 int GS_get_maskmode(int id, int *mode) 01459 { 01460 geosurf *gs; 01461 01462 gs = gs_get_surf(id); 01463 01464 if (gs) { 01465 *mode = gs->att[ATT_MASK].constant; 01466 01467 return (1); 01468 } 01469 01470 return (-1); 01471 } 01472 01482 int GS_Set_ClientData(int id, void *clientd) 01483 { 01484 geosurf *gs; 01485 01486 gs = gs_get_surf(id); 01487 if (gs) { 01488 gs->clientdata = clientd; 01489 01490 return (1); 01491 } 01492 01493 return (-1); 01494 } 01495 01504 void *GS_Get_ClientData(int id) 01505 { 01506 geosurf *gs; 01507 01508 gs = gs_get_surf(id); 01509 if (gs) { 01510 return (gs->clientdata); 01511 } 01512 01513 return (NULL); 01514 } 01515 01521 int GS_num_surfs(void) 01522 { 01523 return (gs_num_surfaces()); 01524 } 01525 01536 int *GS_get_surf_list(int *numsurfs) 01537 { 01538 int i, *ret; 01539 01540 *numsurfs = Next_surf; 01541 01542 if (Next_surf) { 01543 ret = (int *)G_malloc(Next_surf * sizeof(int)); 01544 01545 for (i = 0; i < Next_surf; i++) { 01546 ret[i] = Surf_ID[i]; 01547 } 01548 01549 return (ret); 01550 } 01551 01552 return (NULL); 01553 } 01554 01563 int GS_delete_surface(int id) 01564 { 01565 int i, j, found; 01566 01567 found = FALSE; 01568 01569 G_debug(1, "GS_delete_surface(): id=%d", id); 01570 01571 if (GS_surf_exists(id)) { 01572 gs_delete_surf(id); 01573 for (i = 0; i < Next_surf && !found; i++) { 01574 if (Surf_ID[i] == id) { 01575 found = TRUE; 01576 01577 for (j = i; j < Next_surf; j++) { 01578 Surf_ID[j] = Surf_ID[j + 1]; 01579 } 01580 } 01581 } 01582 01583 gv_update_drapesurfs(); 01584 01585 if (found) { 01586 --Next_surf; 01587 return 1; 01588 } 01589 } 01590 01591 return -1; 01592 } 01593 01594 01605 int GS_load_att_map(int id, const char *filename, int att) 01606 { 01607 geosurf *gs; 01608 unsigned int changed; 01609 unsigned int atty; 01610 const char *mapset; 01611 struct Cell_head rast_head; 01612 int reuse, begin, hdata, ret, neg, has_null; 01613 typbuff *tbuff; 01614 01615 G_debug(3, "GS_load_att_map(): map=%s", filename); 01616 01617 reuse = ret = neg = has_null = 0; 01618 gs = gs_get_surf(id); 01619 01620 if (NULL == gs) { 01621 return -1; 01622 } 01623 01624 gs->mask_needupdate = (ATT_MASK == att || ATT_TOPO == att || 01625 (gs->nz_topo && ATT_TOPO == att) || 01626 (gs->nz_color && ATT_COLOR == att)); 01627 01628 gs_set_att_src(gs, att, MAP_ATT); 01629 01630 /* Check against maps already loaded in memory */ 01631 /* if to be color attribute: 01632 - if packed color for another surface, OK to reuse 01633 - if unchanged, ok to reuse IF it's of type char (will have lookup) 01634 */ 01635 begin = hdata = 1; 01636 01637 /* Get MAPSET to ensure names are fully qualified */ 01638 mapset = G_find_cell2(filename, ""); 01639 if (mapset == NULL) { 01640 /* Check for valid filename */ 01641 G_warning("Raster map <%s> not found", filename); 01642 return -1; 01643 } 01644 01645 /* Check to see if map is in Region */ 01646 G_get_cellhd(filename, mapset, &rast_head); 01647 if (rast_head.north <= wind.south || 01648 rast_head.south >= wind.north || 01649 rast_head.east <= wind.west || rast_head.west >= wind.east) { 01650 01651 G_warning(_("Raster map <%s> is outside of current region. Load failed."), 01652 G_fully_qualified_name(filename, mapset)); 01653 } 01654 01655 while (!reuse && (0 < hdata)) { 01656 changed = CF_COLOR_PACKED; 01657 atty = ATTY_FLOAT | ATTY_CHAR | ATTY_INT | ATTY_SHORT | ATTY_MASK; 01658 01659 if (0 < (hdata = gsds_findh(filename, &changed, &atty, begin))) { 01660 01661 G_debug(3, "GS_load_att_map(): %s already has data handle %d.CF=%x", 01662 filename, hdata, changed); 01663 01664 /* handle found */ 01665 if (ATT_COLOR == att) { 01666 if ((changed == CF_COLOR_PACKED) || 01667 (!changed && atty == ATTY_CHAR)) { 01668 reuse = 1; 01669 } 01670 } 01671 else if (atty == ATTY_MASK && att != ATT_MASK) { 01672 reuse = 0; 01673 /* should also free mask data & share new - but need backward 01674 reference? */ 01675 } 01676 else if (!changed) { 01677 reuse = 1; 01678 } 01679 } 01680 01681 begin = 0; 01682 } 01683 01684 if (reuse) { 01685 gs->att[att].hdata = hdata; 01686 gs_set_att_type(gs, att, atty); /* ?? */ 01687 01688 /* free lookup & set to NULL! */ 01689 if (atty == ATTY_INT) { 01690 if (gs->att[att].lookup) { 01691 free(gs->att[att].lookup); 01692 gs->att[att].lookup = NULL; 01693 } 01694 } 01695 /* TODO: FIX THIS stuff with lookup sharing! */ 01696 01697 G_debug(3, "GS_load_att_map(): %s is being reused. hdata=%d", 01698 filename, hdata); 01699 } 01700 else { 01701 G_debug(3, "GS_load_att_map(): %s not loaded in correct form - loading now", 01702 filename); 01703 01704 /* not loaded - need to get new dataset handle */ 01705 gs->att[att].hdata = gsds_newh(filename); 01706 01707 tbuff = gs_get_att_typbuff(gs, att, 1); 01708 01709 /* TODO: Provide mechanism for loading certain attributes at 01710 specified sizes, allow to scale or cap, or scale non-zero */ 01711 if (ATT_MASK == att) { 01712 atty = ATTY_MASK; 01713 } 01714 else { 01715 atty = Gs_numtype(filename, &neg); 01716 } 01717 01718 #ifdef MAYBE_LATER 01719 if (att == ATT_COLOR && atty == ATTY_SHORT) { 01720 atty = (neg ? ATTY_INT : ATTY_SHORT); 01721 } 01722 #endif 01723 01724 if (att == ATT_COLOR && atty == ATTY_SHORT) { 01725 atty = ATTY_INT; 01726 } 01727 01728 if (0 > gs_malloc_att_buff(gs, att, ATTY_NULL)) { 01729 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map")); 01730 } 01731 01732 switch (atty) { 01733 case ATTY_MASK: 01734 if (0 > gs_malloc_att_buff(gs, att, ATTY_MASK)) { 01735 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map")); 01736 } 01737 01738 ret = Gs_loadmap_as_bitmap(&wind, filename, tbuff->bm); 01739 01740 break; 01741 case ATTY_CHAR: 01742 if (0 > gs_malloc_att_buff(gs, att, ATTY_CHAR)) { 01743 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map")); 01744 } 01745 01746 ret = Gs_loadmap_as_char(&wind, filename, tbuff->cb, 01747 tbuff->nm, &has_null); 01748 01749 break; 01750 case ATTY_SHORT: 01751 if (0 > gs_malloc_att_buff(gs, att, ATTY_SHORT)) { 01752 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map")); 01753 } 01754 01755 ret = Gs_loadmap_as_short(&wind, filename, tbuff->sb, 01756 tbuff->nm, &has_null); 01757 break; 01758 case ATTY_FLOAT: 01759 if (0 > gs_malloc_att_buff(gs, att, ATTY_FLOAT)) { 01760 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map")); 01761 } 01762 01763 ret = Gs_loadmap_as_float(&wind, filename, tbuff->fb, 01764 tbuff->nm, &has_null); 01765 01766 break; 01767 case ATTY_INT: 01768 default: 01769 if (0 > gs_malloc_att_buff(gs, att, ATTY_INT)) { 01770 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map")); 01771 } 01772 01773 ret = Gs_loadmap_as_int(&wind, filename, tbuff->ib, 01774 tbuff->nm, &has_null); 01775 break; 01776 01777 } /* Done with switch */ 01778 01779 if (ret == -1) { 01780 gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL); 01781 return -1; 01782 } 01783 01784 G_debug(4, " has_null=%d", has_null); 01785 01786 if (!has_null) { 01787 gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL); 01788 } 01789 else { 01790 gs_update_curmask(gs); 01791 } 01792 01793 } /* end if not reuse */ 01794 01795 if (ATT_COLOR == att) { 01796 #ifdef MAYBE_LATER 01797 if (ATTY_INT == atty) { 01798 Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols); 01799 gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED); 01800 gs->att[att].lookup = NULL; 01801 } 01802 else { 01803 gs_malloc_lookup(gs, att); 01804 Gs_build_lookup(filename, gs->att[att].lookup); 01805 } 01806 #else 01807 01808 if (ATTY_CHAR == atty) { 01809 if (!gs->att[att].lookup) { 01810 /* might already exist if reusing */ 01811 gs_malloc_lookup(gs, att); 01812 Gs_build_256lookup(filename, gs->att[att].lookup); 01813 } 01814 } 01815 else if (ATTY_FLOAT == atty) { 01816 if (!reuse) { 01817 if (0 > gs_malloc_att_buff(gs, att, ATTY_INT)) { 01818 G_fatal_error(_("GS_load_att_map(): Out of memory. Unable to load map")); 01819 } 01820 01821 Gs_pack_colors_float(filename, tbuff->fb, tbuff->ib, 01822 gs->rows, gs->cols); 01823 gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED); 01824 gsds_free_data_buff(gs->att[att].hdata, ATTY_FLOAT); 01825 gs->att[att].lookup = NULL; 01826 } 01827 } 01828 else { 01829 if (!reuse) { 01830 Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols); 01831 gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED); 01832 gs->att[att].lookup = NULL; 01833 } 01834 } 01835 #endif 01836 } 01837 01838 if (ATT_TOPO == att) { 01839 gs_init_normbuff(gs); 01840 /* S_DIFF: should also check here to see if this surface is a 01841 reference surface for scaled differences, if so update references 01842 to it */ 01843 } 01844 01845 if (ret < 0) { 01846 G_warning(_("Loading failed")); 01847 } 01848 01849 if (-1 == Gs_update_attrange(gs, att)) { 01850 G_warning(_("Error finding range")); 01851 } 01852 01853 return ret; 01854 } 01855 01861 void GS_draw_surf(int id) 01862 { 01863 geosurf *gs; 01864 01865 G_debug(3, "GS_draw_surf(): id=%d", id); 01866 01867 gs = gs_get_surf(id); 01868 if (gs) { 01869 gsd_shademodel(gs->draw_mode & DM_GOURAUD); 01870 01871 if (gs->draw_mode & DM_POLY) { 01872 gsd_surf(gs); 01873 } 01874 01875 if (gs->draw_mode & DM_WIRE) { 01876 gsd_wire_surf(gs); 01877 } 01878 01879 /* TODO: write wire/poly draw routines */ 01880 if (gs->draw_mode & DM_WIRE_POLY) { 01881 gsd_surf(gs); 01882 gsd_wire_surf(gs); 01883 } 01884 } 01885 01886 return; 01887 } 01888 01896 void GS_draw_wire(int id) 01897 { 01898 geosurf *gs; 01899 01900 G_debug(3, "GS_draw_wire(): id=%d", id); 01901 01902 gs = gs_get_surf(id); 01903 01904 if (gs) { 01905 gsd_wire_surf(gs); 01906 } 01907 01908 return; 01909 } 01910 01916 void GS_alldraw_wire(void) 01917 { 01918 geosurf *gs; 01919 int i; 01920 01921 for (i = 0; i < Next_surf; i++) { 01922 if ((gs = gs_get_surf(Surf_ID[i]))) { 01923 gsd_wire_surf(gs); 01924 } 01925 } 01926 01927 return; 01928 } 01929 01933 void GS_alldraw_surf(void) 01934 { 01935 int i; 01936 01937 for (i = 0; i < Next_surf; i++) { 01938 GS_draw_surf(Surf_ID[i]); 01939 } 01940 01941 return; 01942 } 01943 01950 void GS_set_exag(int id, float exag) 01951 { 01952 geosurf *gs; 01953 01954 G_debug(3, "GS_set_exag"); 01955 01956 gs = gs_get_surf(id); 01957 01958 if (gs) { 01959 if (gs->z_exag != exag) { 01960 gs->norm_needupdate = 1; 01961 } 01962 01963 gs->z_exag = exag; 01964 } 01965 01966 return; 01967 } 01968 01974 void GS_set_global_exag(float exag) 01975 { 01976 01977 G_debug(3, "GS_set_global_exag"); 01978 01979 Gv.vert_exag = exag; 01980 /* GL_NORMALIZE */ 01981 /* Only need to update norms gs_norms.c 01982 * if exag is used in norm equation which 01983 * it is not! If GL_NORMALIZE is disabled 01984 * will need to include. 01985 gs_setall_norm_needupdate(); 01986 */ 01987 01988 return; 01989 } 01990 01996 float GS_global_exag(void) 01997 { 01998 G_debug(3, "GS_global_exag(): %g", Gv.vert_exag); 01999 02000 return (Gv.vert_exag); 02001 } 02002 02011 void GS_set_wire_color(int id, int colr) 02012 { 02013 geosurf *gs; 02014 02015 G_debug(3, "GS_set_wire_color"); 02016 02017 gs = gs_get_surf(id); 02018 02019 if (gs) { 02020 gs->wire_color = colr; 02021 } 02022 02023 return; 02024 } 02025 02035 int GS_get_wire_color(int id, int *colr) 02036 { 02037 geosurf *gs; 02038 02039 gs = gs_get_surf(id); 02040 02041 if (gs) { 02042 *colr = gs->wire_color; 02043 02044 return (1); 02045 } 02046 02047 return (-1); 02048 } 02049 02058 int GS_setall_drawmode(int mode) 02059 { 02060 int i; 02061 02062 for (i = 0; i < Next_surf; i++) { 02063 if (0 != GS_set_drawmode(Surf_ID[i], mode)) { 02064 return (-1); 02065 } 02066 } 02067 02068 return (0); 02069 } 02070 02080 int GS_set_drawmode(int id, int mode) 02081 { 02082 geosurf *gs; 02083 02084 G_debug(3, "GS_set_drawmode(): id=%d mode=%d", id, mode); 02085 02086 gs = gs_get_surf(id); 02087 02088 if (gs) { 02089 gs->draw_mode = mode; 02090 02091 return (0); 02092 } 02093 02094 return (-1); 02095 } 02096 02106 int GS_get_drawmode(int id, int *mode) 02107 { 02108 geosurf *gs; 02109 02110 gs = gs_get_surf(id); 02111 02112 if (gs) { 02113 *mode = gs->draw_mode; 02114 02115 return (1); 02116 } 02117 02118 return (-1); 02119 } 02120 02128 void GS_set_nozero(int id, int att, int mode) 02129 { 02130 geosurf *gs; 02131 02132 G_debug(3, "GS_set_nozero"); 02133 02134 gs = gs_get_surf(id); 02135 02136 if (gs) { 02137 if (att == ATT_TOPO) { 02138 gs->nz_topo = mode; 02139 gs->mask_needupdate = 1; 02140 } 02141 02142 if (att == ATT_COLOR) { 02143 gs->nz_color = mode; 02144 gs->mask_needupdate = 1; 02145 } 02146 } 02147 02148 return; 02149 } 02150 02161 int GS_get_nozero(int id, int att, int *mode) 02162 { 02163 geosurf *gs; 02164 02165 G_debug(3, "GS_set_nozero"); 02166 02167 gs = gs_get_surf(id); 02168 02169 if (gs) { 02170 if (att == ATT_TOPO) { 02171 *mode = gs->nz_topo; 02172 } 02173 else if (att == ATT_COLOR) { 02174 *mode = gs->nz_color; 02175 } 02176 else { 02177 return (-1); 02178 } 02179 02180 return (1); 02181 } 02182 02183 return (-1); 02184 } 02185 02195 int GS_setall_drawres(int xres, int yres, int xwire, int ywire) 02196 { 02197 int i; 02198 02199 for (i = 0; i < Next_surf; i++) { 02200 if (0 != GS_set_drawres(Surf_ID[i], xres, yres, xwire, ywire)) { 02201 return (-1); 02202 } 02203 } 02204 02205 return (0); 02206 } 02207 02218 int GS_set_drawres(int id, int xres, int yres, int xwire, int ywire) 02219 { 02220 geosurf *gs; 02221 02222 G_debug(3, "GS_set_drawres() id=%d xyres=%d/%d xywire=%d/%d", 02223 id, xres, yres, xwire, ywire); 02224 02225 if (xres < 1 || yres < 1 || xwire < 1 || ywire < 1) { 02226 return (-1); 02227 } 02228 02229 gs = gs_get_surf(id); 02230 02231 if (gs) { 02232 if (gs->x_mod != xres || gs->y_mod != yres) { 02233 gs->norm_needupdate = 1; 02234 } 02235 02236 gs->x_mod = xres; 02237 gs->y_mod = yres; 02238 gs->x_modw = xwire; 02239 gs->y_modw = ywire; 02240 } 02241 02242 return (0); 02243 } 02244 02252 void GS_get_drawres(int id, int *xres, int *yres, int *xwire, int *ywire) 02253 { 02254 geosurf *gs; 02255 02256 G_debug(3, "GS_get_drawres"); 02257 02258 gs = gs_get_surf(id); 02259 02260 if (gs) { 02261 *xres = gs->x_mod; 02262 *yres = gs->y_mod; 02263 *xwire = gs->x_modw; 02264 *ywire = gs->y_modw; 02265 } 02266 02267 return; 02268 } 02269 02276 void GS_get_dims(int id, int *rows, int *cols) 02277 { 02278 geosurf *gs; 02279 02280 gs = gs_get_surf(id); 02281 02282 if (gs) { 02283 *rows = gs->rows; 02284 *cols = gs->cols; 02285 } 02286 02287 return; 02288 } 02289 02303 int GS_get_exag_guess(int id, float *exag) 02304 { 02305 geosurf *gs; 02306 float guess; 02307 02308 gs = gs_get_surf(id); 02309 guess = 1.0; 02310 02311 /* if gs is type const return guess = 1.0 */ 02312 if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) { 02313 return (1); 02314 } 02315 02316 if (gs) { 02317 if (gs->zrange_nz == 0.0) { 02318 *exag = 0.0; 02319 02320 return (1); 02321 } 02322 02323 G_debug(3, "GS_get_exag_guess(): %f %f", gs->zrange_nz, Longdim); 02324 02325 while (gs->zrange_nz * guess / Longdim >= .25) { 02326 guess *= .1; 02327 02328 G_debug(3, "GS_get_exag_guess(): %f", guess); 02329 } 02330 02331 while (gs->zrange_nz * guess / Longdim < .025) { 02332 guess *= 10.; 02333 02334 G_debug(3, "GS_get_exag_guess(): %f", guess); 02335 } 02336 02337 *exag = guess; 02338 02339 return (1); 02340 } 02341 02342 return (-1); 02343 } 02344 02353 void GS_get_zrange_nz(float *min, float *max) 02354 { 02355 int i, first = 1; 02356 geosurf *gs; 02357 02358 for (i = 0; i < Next_surf; i++) { 02359 if ((gs = gs_get_surf(Surf_ID[i]))) { 02360 if (first) { 02361 first = 0; 02362 *min = gs->zmin_nz; 02363 *max = gs->zmax_nz; 02364 } 02365 02366 if (gs->zmin_nz < *min) { 02367 *min = gs->zmin_nz; 02368 } 02369 02370 if (gs->zmax_nz > *max) { 02371 *max = gs->zmax_nz; 02372 } 02373 } 02374 } 02375 02376 G_debug(3, "GS_get_zrange_nz(): min=%g max=%g", *min, *max); 02377 02378 return; 02379 } 02380 02387 void GS_set_trans(int id, float xtrans, float ytrans, float ztrans) 02388 { 02389 geosurf *gs; 02390 02391 G_debug(3, "GS_set_trans"); 02392 02393 gs = gs_get_surf(id); 02394 02395 if (gs) { 02396 gs->x_trans = xtrans; 02397 gs->y_trans = ytrans; 02398 gs->z_trans = ztrans; 02399 } 02400 02401 return; 02402 } 02403 02410 void GS_get_trans(int id, float *xtrans, float *ytrans, float *ztrans) 02411 { 02412 geosurf *gs; 02413 02414 G_debug(3, "GS_get_trans"); 02415 02416 gs = gs_get_surf(id); 02417 02418 if (gs) { 02419 *xtrans = gs->x_trans; 02420 *ytrans = gs->y_trans; 02421 *ztrans = gs->z_trans; 02422 } 02423 02424 return; 02425 } 02426 02427 02433 unsigned int GS_default_draw_color(void) 02434 { 02435 02436 G_debug(3, "GS_default_draw_color"); 02437 02438 return ((unsigned int)Gd.bgcol); 02439 } 02440 02446 unsigned int GS_background_color(void) 02447 { 02448 return ((unsigned int)Gd.bgcol); 02449 } 02450 02456 void GS_set_draw(int where) 02457 { 02458 Buffermode = where; 02459 02460 switch (where) { 02461 case GSD_BOTH: 02462 gsd_frontbuffer(1); 02463 gsd_backbuffer(1); 02464 02465 break; 02466 case GSD_FRONT: 02467 gsd_frontbuffer(1); 02468 gsd_backbuffer(0); 02469 02470 break; 02471 case GSD_BACK: 02472 default: 02473 gsd_frontbuffer(0); 02474 gsd_backbuffer(1); 02475 02476 break; 02477 } 02478 02479 return; 02480 } 02481 02482 /* 02483 \brief Ready to draw 02484 */ 02485 void GS_ready_draw(void) 02486 { 02487 02488 G_debug(3, "GS_ready_draw"); 02489 02490 gsd_set_view(&Gv, &Gd); 02491 02492 return; 02493 } 02494 02498 void GS_done_draw(void) 02499 { 02500 02501 G_debug(3, "GS_done_draw"); 02502 02503 if (GSD_BACK == Buffermode) { 02504 gsd_swapbuffers(); 02505 } 02506 02507 gsd_flush(); 02508 02509 return; 02510 } 02511 02517 void GS_set_focus(float *realto) 02518 { 02519 02520 G_debug(3, "GS_set_focus(): %f,%f,%f", realto[0], realto[1], realto[2]); 02521 02522 Gv.infocus = 1; 02523 GS_v3eq(Gv.real_to, realto); 02524 02525 gsd_set_view(&Gv, &Gd); 02526 02527 return; 02528 } 02529 02535 void GS_set_focus_real(float *realto) 02536 { 02537 02538 G_get_set_window(&wind); 02539 realto[X] = realto[X] - wind.west - (wind.ew_res / 2.); 02540 realto[Y] = realto[Y] - wind.south - (wind.ns_res / 2.); 02541 02542 Gv.infocus = 1; 02543 GS_v3eq(Gv.real_to, realto); 02544 02545 gsd_set_view(&Gv, &Gd); 02546 02547 return; 02548 } 02549 02550 02560 int GS_get_focus(float *realto) 02561 { 02562 02563 G_debug(3, "GS_get_focus"); 02564 02565 if (Gv.infocus) { 02566 if (realto) { 02567 GS_v3eq(realto, Gv.real_to); 02568 } 02569 } 02570 02571 return (Gv.infocus); 02572 } 02573 02579 void GS_set_focus_center_map(int id) 02580 { 02581 float center[3]; 02582 geosurf *gs; 02583 02584 G_debug(3, "GS_set_focus_center_map"); 02585 02586 gs = gs_get_surf(id); 02587 02588 if (gs) { 02589 center[X] = (gs->xmax - gs->xmin) / 2.; 02590 center[Y] = (gs->ymax - gs->ymin) / 2.; 02591 center[Z] = (gs->zmax_nz + gs->zmin_nz) / 2.; 02592 02593 /* not yet working 02594 buff = gs_get_att_typbuff(gs, ATT_TOPO, 0); 02595 offset = gs->rows*gs->cols/2 + gs->cols/2; 02596 if (buff) 02597 { 02598 if (GET_MAPATT(buff, offset, tmp)) 02599 { 02600 center[Z] = tmp; 02601 } 02602 } 02603 */ 02604 02605 GS_set_focus(center); 02606 } 02607 } 02608 02614 void GS_moveto(float *pt) 02615 { 02616 float ft[3]; 02617 02618 G_debug(3, "GS_moveto(): %f,%f,%f", pt[0], pt[1], pt[2]); 02619 02620 if (Gv.infocus) { 02621 GS_v3eq(Gv.from_to[FROM], pt); 02622 /* 02623 GS_v3eq(Gv.from_to[TO], Gv.real_to); 02624 */ 02625 GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]); 02626 /* update inclination, look_dir if we're keeping these */ 02627 } 02628 else { 02629 GS_v3eq(ft, Gv.from_to[TO]); 02630 GS_v3sub(ft, Gv.from_to[FROM]); 02631 GS_v3eq(Gv.from_to[FROM], pt); 02632 GS_v3eq(Gv.from_to[TO], pt); 02633 GS_v3add(Gv.from_to[TO], ft); 02634 } 02635 02636 return; 02637 } 02638 02644 void GS_moveto_real(float *pt) 02645 { 02646 gsd_real2model(pt); 02647 GS_moveto(pt); 02648 02649 return; 02650 } 02651 02663 int GS_get_zextents(int id, float *min, float *max, float *mid) 02664 { 02665 geosurf *gs; 02666 02667 if (NULL == (gs = gs_get_surf(id))) { 02668 return (-1); 02669 } 02670 02671 G_debug(3, "GS_get_zextents(): id=%d", id); 02672 02673 return (gs_get_zextents(gs, min, max, mid)); 02674 } 02675 02686 int GS_get_zrange(float *min, float *max, int doexag) 02687 { 02688 int ret_surf, ret_vol; 02689 float surf_min, surf_max; 02690 float vol_min, vol_max; 02691 02692 ret_surf = gs_get_zrange(&surf_min, &surf_max); 02693 ret_vol = gvl_get_zrange(&vol_min, &vol_max); 02694 02695 if (ret_surf > 0 && ret_vol > 0) { 02696 *min = (surf_min < vol_min) ? surf_min : vol_min; 02697 *max = (surf_max < vol_max) ? surf_max : vol_max; 02698 } 02699 else if (ret_surf > 0) { 02700 *min = surf_min; 02701 *max = surf_max; 02702 } 02703 else if (ret_vol > 0) { 02704 *min = vol_min; 02705 *max = vol_max; 02706 } 02707 02708 if (doexag) { 02709 *min *= Gv.vert_exag; 02710 *max *= Gv.vert_exag; 02711 } 02712 02713 G_debug(3, "GS_get_zrange(): min=%g max=%g", *min, *max); 02714 return ((ret_surf > 0 || ret_vol > 0) ? (1) : (-1)); 02715 } 02716 02722 void GS_get_from(float *fr) 02723 { 02724 GS_v3eq(fr, Gv.from_to[FROM]); 02725 02726 G_debug(3, "GS_get_from(): %f,%f,%f", fr[0], fr[1], fr[2]); 02727 02728 return; 02729 } 02730 02736 void GS_get_from_real(float *fr) 02737 { 02738 GS_v3eq(fr, Gv.from_to[FROM]); 02739 gsd_model2real(fr); 02740 02741 return; 02742 } 02743 02749 void GS_get_to_real(float *to) 02750 { 02751 float realto[3]; 02752 02753 G_get_set_window(&wind); 02754 GS_get_focus(realto); 02755 to[X] = realto[X] + wind.west + (wind.ew_res / 2.); 02756 to[Y] = realto[Y] + wind.south + (wind.ns_res / 2.); 02757 to[Z] = realto[Z]; 02758 02759 return; 02760 } 02761 02762 02769 void GS_zoom_setup(int *a, int *b, int *c, int *d, int *maxx, int *maxy) 02770 { 02771 GLint tmp[4]; 02772 GLint num[2]; 02773 02774 gsd_getViewport(tmp, num); 02775 *a = tmp[0]; 02776 *b = tmp[1]; 02777 *c = tmp[2]; 02778 *d = tmp[3]; 02779 *maxx = num[0]; 02780 *maxy = num[1]; 02781 02782 return; 02783 } 02784 02792 void GS_get_to(float *to) 02793 { 02794 G_debug(3, "GS_get_to"); 02795 02796 GS_v3eq(to, Gv.from_to[TO]); 02797 02798 return; 02799 } 02800 02806 void GS_get_viewdir(float *dir) 02807 { 02808 GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir); 02809 02810 return; 02811 } 02812 02820 void GS_set_viewdir(float *dir) 02821 { 02822 float tmp[3]; 02823 02824 GS_v3eq(tmp, dir); 02825 GS_v3norm(tmp); 02826 GS_v3eq(Gv.from_to[TO], Gv.from_to[FROM]); 02827 GS_v3add(Gv.from_to[TO], tmp); 02828 02829 GS_set_nofocus(); 02830 gsd_set_view(&Gv, &Gd); 02831 02832 return; 02833 } 02834 02840 void GS_set_fov(int fov) 02841 { 02842 Gv.fov = fov; 02843 02844 return; 02845 } 02846 02852 int GS_get_fov(void) 02853 { 02854 return (Gv.fov); 02855 } 02856 02862 int GS_get_twist(void) 02863 { 02864 return (Gv.twist); 02865 } 02866 02874 void GS_set_twist(int t) 02875 { 02876 Gv.twist = t; 02877 02878 return; 02879 } 02880 02884 void GS_set_rotation(double angle, double x, double y, double z) 02885 { 02886 Gv.rotate.rot_angle = angle; 02887 Gv.rotate.rot_axes[0] = x; 02888 Gv.rotate.rot_axes[1] = y; 02889 Gv.rotate.rot_axes[2] = z; 02890 Gv.rotate.do_rot = 1; 02891 02892 return; 02893 } 02894 02898 void GS_unset_rotation(void) 02899 { 02900 Gv.rotate.do_rot = 0; 02901 } 02902 02906 void GS_init_rotation(void) 02907 { 02908 int i; 02909 02910 for (i = 0; i < 16; i++) { 02911 if (i == 0 || i == 5 || i == 10 || i == 15) 02912 Gv.rotate.rotMatrix[i] = 1.0; 02913 else 02914 Gv.rotate.rotMatrix[i] = 0.0; 02915 } 02916 Gv.rotate.rot_angle = 0.0; 02917 Gv.rotate.rot_axes[0] = 0.0; 02918 Gv.rotate.rot_axes[1] = 0.0; 02919 Gv.rotate.rot_axes[2] = 0.0; 02920 Gv.rotate.do_rot = 0; 02921 02922 } 02926 void GS_get_rotation_matrix(double *matrix) 02927 { 02928 int i; 02929 02930 for (i = 0; i < 16; i++) { 02931 matrix[i] = Gv.rotate.rotMatrix[i]; 02932 } 02933 } 02934 02938 void GS_set_rotation_matrix(double *matrix) 02939 { 02940 int i; 02941 02942 for (i = 0; i < 16; i++) { 02943 Gv.rotate.rotMatrix[i] = matrix[i]; 02944 } 02945 } 02946 02950 void GS_set_nofocus(void) 02951 { 02952 G_debug(3, "GS_set_nofocus"); 02953 02954 Gv.infocus = 0; 02955 02956 return; 02957 } 02958 02964 void GS_set_infocus(void) 02965 { 02966 G_debug(3, "GS_set_infocus"); 02967 02968 Gv.infocus = 1; 02969 02970 return; 02971 } 02972 02978 void GS_set_viewport(int left, int right, int bottom, int top) 02979 { 02980 G_debug(3, "GS_set_viewport(): left=%d, right=%d, " 02981 "bottom=%d, top=%d", left, right, bottom, top); 02982 02983 gsd_viewport(left, right, bottom, top); 02984 02985 return; 02986 } 02987 03002 int GS_look_here(int sx, int sy) 03003 { 03004 float x, y, z, len, los[2][3]; 03005 Point3 realto, dir; 03006 int id; 03007 geosurf *gs; 03008 03009 if (GS_get_selected_point_on_surface(sx, sy, &id, &x, &y, &z)) { 03010 gs = gs_get_surf(id); 03011 if (gs) { 03012 realto[X] = x - gs->ox + gs->x_trans; 03013 realto[Y] = y - gs->oy + gs->y_trans; 03014 realto[Z] = z + gs->z_trans; 03015 GS_set_focus(realto); 03016 03017 return (1); 03018 } 03019 } 03020 else { 03021 if (gsd_get_los(los, (short)sx, (short)sy)) { 03022 len = GS_distance(Gv.from_to[FROM], Gv.real_to); 03023 GS_v3dir(los[FROM], los[TO], dir); 03024 GS_v3mult(dir, len); 03025 realto[X] = Gv.from_to[FROM][X] + dir[X]; 03026 realto[Y] = Gv.from_to[FROM][Y] + dir[Y]; 03027 realto[Z] = Gv.from_to[FROM][Z] + dir[Z]; 03028 GS_set_focus(realto); 03029 03030 return (1); 03031 } 03032 } 03033 03034 return (0); 03035 } 03036 03051 int GS_get_selected_point_on_surface(int sx, int sy, int *id, float *x, 03052 float *y, float *z) 03053 { 03054 float los[2][3], find_dist[MAX_SURFS], closest; 03055 Point3 point, tmp, finds[MAX_SURFS]; 03056 int surfs[MAX_SURFS], i, iclose, numhits = 0; 03057 geosurf *gs; 03058 03059 /* returns surface-world coords */ 03060 gsd_get_los(los, (short)sx, (short)sy); 03061 03062 if (!gs_setlos_enterdata(los)) { 03063 G_debug(3, "gs_setlos_enterdata(los): returns false"); 03064 return (0); 03065 } 03066 03067 for (i = 0; i < Next_surf; i++) { 03068 G_debug(3, "id=%d", i); 03069 03070 gs = gs_get_surf(Surf_ID[i]); 03071 03072 /* los_intersect expects surf-world coords (xy transl, no scaling) */ 03073 03074 #if NVIZ_HACK 03075 if (gs_los_intersect1(Surf_ID[i], los, point)) { 03076 #else 03077 if (gs_los_intersect(Surf_ID[i], los, point)) { 03078 #endif 03079 if (!gs_point_is_masked(gs, point)) { 03080 GS_v3eq(tmp, point); 03081 tmp[X] += gs->x_trans; 03082 tmp[Y] += gs->y_trans; 03083 tmp[Z] += gs->z_trans; 03084 find_dist[numhits] = GS_distance(los[FROM], tmp); 03085 gsd_surf2real(gs, point); 03086 GS_v3eq(finds[numhits], point); 03087 surfs[numhits] = Surf_ID[i]; 03088 numhits++; 03089 } 03090 } 03091 } 03092 03093 for (i = iclose = 0; i < numhits; i++) { 03094 closest = find_dist[iclose]; 03095 03096 if (find_dist[i] < closest) { 03097 iclose = i; 03098 } 03099 } 03100 03101 if (numhits) { 03102 *x = finds[iclose][X]; 03103 *y = finds[iclose][Y]; 03104 *z = finds[iclose][Z]; 03105 *id = surfs[iclose]; 03106 } 03107 03108 G_debug(3, "NumHits %d, next %d", numhits, Next_surf); 03109 03110 return (numhits); 03111 } 03112 03119 void GS_set_cplane_rot(int num, float dx, float dy, float dz) 03120 { 03121 gsd_cplane_setrot(num, dx, dy, dz); 03122 03123 return; 03124 } 03125 03132 void GS_set_cplane_trans(int num, float dx, float dy, float dz) 03133 { 03134 gsd_cplane_settrans(num, dx, dy, dz); 03135 03136 return; 03137 } 03138 03139 03145 void GS_draw_cplane(int num) 03146 { 03147 geosurf *gsurfs[MAX_SURFS]; 03148 int nsurfs; 03149 03150 nsurfs = gs_num_surfaces(); 03151 if (2 == nsurfs) { 03152 /* testing */ 03153 gs_getall_surfaces(gsurfs); 03154 gsd_draw_cplane_fence(gsurfs[0], gsurfs[1], num); 03155 } 03156 else { 03157 gsd_draw_cplane(num); 03158 } 03159 03160 return; 03161 } 03162 03172 int GS_draw_cplane_fence(int hs1, int hs2, int num) 03173 { 03174 geosurf *gs1, *gs2; 03175 03176 if (NULL == (gs1 = gs_get_surf(hs1))) { 03177 return (0); 03178 } 03179 03180 if (NULL == (gs2 = gs_get_surf(hs2))) { 03181 return (0); 03182 } 03183 03184 gsd_draw_cplane_fence(gs1, gs2, num); 03185 03186 return (1); 03187 } 03188 03192 void GS_alldraw_cplane_fences(void) 03193 { 03194 int onstate[MAX_CPLANES], i; 03195 03196 gsd_get_cplanes_state(onstate); 03197 03198 for (i = 0; i < MAX_CPLANES; i++) { 03199 if (onstate[i]) { 03200 GS_draw_cplane_fence(Surf_ID[0], Surf_ID[1], i); 03201 } 03202 } 03203 03204 return; 03205 } 03206 03212 void GS_set_cplane(int num) 03213 { 03214 gsd_cplane_on(num); 03215 03216 return; 03217 } 03218 03224 void GS_unset_cplane(int num) 03225 { 03226 gsd_cplane_off(num); 03227 03228 return; 03229 } 03230 03237 void GS_get_scale(float *sx, float *sy, float *sz, int doexag) 03238 { 03239 float zexag; 03240 03241 zexag = doexag ? Gv.vert_exag : 1.; 03242 *sx = *sy = Gv.scale; 03243 *sz = Gv.scale * zexag; 03244 03245 return; 03246 } 03247 03253 void GS_set_fencecolor(int mode) 03254 { 03255 gsd_setfc(mode); 03256 03257 return; 03258 } 03259 03265 int GS_get_fencecolor(void) 03266 { 03267 return gsd_getfc(); 03268 } 03269 03282 int GS_get_distance_alongsurf(int hs, float x1, float y1, float x2, float y2, 03283 float *dist, int use_exag) 03284 { 03285 geosurf *gs; 03286 float p1[2], p2[2]; 03287 03288 gs = gs_get_surf(hs); 03289 if (gs == NULL) { 03290 return 0; 03291 } 03292 03293 p1[X] = x1; 03294 p1[Y] = y1; 03295 p2[X] = x2; 03296 p2[Y] = y2; 03297 gsd_real2surf(gs, p1); 03298 gsd_real2surf(gs, p2); 03299 03300 G_debug(3, "GS_get_distance_alongsurf(): hs=%d p1=%f,%f p2=%f,%f", 03301 hs, x1, y1, x2, y2); 03302 return gs_distance_onsurf(gs, p1, p2, dist, use_exag); 03303 } 03304 03313 int GS_save_3dview(const char *vname, int surfid) 03314 { 03315 return (Gs_save_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid))); 03316 } 03317 03326 int GS_load_3dview(const char *vname, int surfid) 03327 { 03328 03329 return (Gs_load_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid))); 03330 03331 /* what to do about lights - I guess, delete all & 03332 create any that exist in 3dview file */ 03333 } 03334 03335 /************************************************************************ 03336 * Following routines use Graphics Library 03337 ************************************************************************/ 03338 03344 void GS_init_view(void) 03345 { 03346 int i; 03347 static int first = 1; 03348 03349 G_debug(3, "GS_init_view"); 03350 03351 if (first) { 03352 first = 0; 03353 glMatrixMode(GL_MODELVIEW); 03354 03355 /* OGLXXX doublebuffer: use GLX_DOUBLEBUFFER in attriblist */ 03356 /* glxChooseVisual(*dpy, screen, *attriblist); */ 03357 /* OGLXXX 03358 * ZMIN not needed -- always 0. 03359 * ZMAX not needed -- always 1. 03360 * getgdesc other posiblilties: 03361 * glxGetConfig(); 03362 * glxGetCurrentContext(); 03363 * glxGetCurrentDrawable(); 03364 * GLint gdtmp; 03365 * getgdesc other posiblilties: 03366 * glxGetConfig(); 03367 * glxGetCurrentContext(); 03368 * glxGetCurrentDrawable(); 03369 * GLint gdtmp; 03370 * glDepthRange params must be scaled to [0, 1] 03371 */ 03372 glDepthRange(0.0, 1.0); 03373 glEnable(GL_DEPTH_TEST); 03374 glDepthFunc(GL_LEQUAL); 03375 /* } */ 03376 03377 /* replace these with something meaningful */ 03378 Gv.fov = 450; 03379 Gv.twist = 0; 03380 03381 GS_init_rotation(); 03382 03383 Gv.from_to[FROM][X] = Gv.from_to[FROM][Y] = 03384 Gv.from_to[FROM][Z] = GS_UNIT_SIZE / 2.; 03385 03386 Gv.from_to[TO][X] = GS_UNIT_SIZE / 2.; 03387 Gv.from_to[TO][Y] = GS_UNIT_SIZE / 2.; 03388 Gv.from_to[TO][Z] = 0.; 03389 Gv.from_to[TO][W] = Gv.from_to[FROM][W] = 1.; 03390 03391 Gv.real_to[W] = 1.; 03392 Gv.vert_exag = 1.; 03393 03394 GS_v3eq(Gv.real_to, Gv.from_to[TO]); 03395 GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]); 03396 03397 /* 03398 Gd.nearclip = 50; 03399 Gd.farclip = 10000.; 03400 */ 03401 Gd.nearclip = 10.; 03402 Gd.farclip = 10000.; 03403 Gd.aspect = (float)GS_get_aspect(); 03404 03405 GS_set_focus(Gv.real_to); 03406 } 03407 03408 return; 03409 } 03410 03416 void GS_clear(int col) 03417 { 03418 G_debug(3, "GS_clear"); 03419 03420 col = col | 0xFF000000; 03421 03422 /* OGLXXX 03423 * change glClearDepth parameter to be in [0, 1] 03424 * ZMAX not needed -- always 1. 03425 * getgdesc other posiblilties: 03426 * glxGetConfig(); 03427 * glxGetCurrentContext(); 03428 * glxGetCurrentDrawable(); 03429 * GLint gdtmp; 03430 */ 03431 glClearDepth(1.0); 03432 glClearColor(((float)((col) & 0xff)) / 255., 03433 (float)((col) >> 8 & 0xff) / 255., 03434 (float)((col) >> 16 & 0xff) / 255., 03435 (float)((col) >> 24 & 0xff) / 255.); 03436 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 03437 03438 Gd.bgcol = col; 03439 Modelshowing = 0; 03440 gsd_flush(); 03441 03442 return; 03443 } 03444 03450 double GS_get_aspect(void) 03451 { 03452 int left, right, bottom, top; 03453 GLint tmp[4]; 03454 03455 /* OGLXXX 03456 * get GL_VIEWPORT: 03457 * You can probably do better than this. 03458 */ 03459 glGetIntegerv(GL_VIEWPORT, tmp); 03460 left = tmp[0]; 03461 right = tmp[0] + tmp[2] - 1; 03462 bottom = tmp[1]; 03463 top = tmp[1] + tmp[3] - 1; 03464 03465 G_debug(3, "GS_get_aspect(): left=%d, right=%d, top=%d, bottom=%d", 03466 left, right, top, bottom); 03467 03468 return ((double)(right - left) / (top - bottom)); 03469 } 03470 03478 int GS_has_transparency(void) 03479 { 03480 /* OGLXXX 03481 * getgdesc other posiblilties: 03482 * glxGetConfig(); 03483 * glxGetCurrentContext(); 03484 * glxGetCurrentDrawable(); 03485 * GLint gdtmp; 03486 * blending is ALWAYS supported. 03487 * This function returns whether it is enabled. 03488 * return((glGetIntegerv(GL_BLEND, &gdtmp), gdtmp)); 03489 */ 03490 03491 return (1); 03492 }