GS2.c 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414
  1. /*!
  2. \file GS2.c
  3. \brief OGSF library - loading and manipulating surfaces (higher level functions)
  4. GRASS OpenGL gsurf OGSF Library
  5. Plans for handling color maps:
  6. NOW:
  7. if able to load as unsigned char, make lookup table containing palette
  8. otherwise, load directly as packed color, set lookup = NULL
  9. MAYBE LATER:
  10. if able to load as POSITIVE short, make lookup table containing palette
  11. - may want to calculate savings first (ie, numcells > 32768)
  12. (not exactly, it's Friday & time to go home - figure it later)
  13. otherwise, load directly as packed color, set lookup = NULL
  14. MESSY! - need to fix up!
  15. (C) 1999-2008 by the GRASS Development Team
  16. This program is free software under the
  17. GNU General Public License (>=v2).
  18. Read the file COPYING that comes with GRASS
  19. for details.
  20. \author Bill Brown USACERL (1993)
  21. \author Pierre de Mouveaux <p_de_mouveaux hotmail.com> (updated October 1999)
  22. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  23. */
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <math.h>
  27. #include <grass/config.h>
  28. #if defined(OPENGL_X11) || defined(OPENGL_WINDOWS)
  29. #include <GL/gl.h>
  30. #include <GL/glu.h>
  31. #elif defined(OPENGL_AQUA)
  32. #include <OpenGL/gl.h>
  33. #include <OpenGL/glu.h>
  34. #endif
  35. #include <grass/gis.h>
  36. #include <grass/gstypes.h>
  37. #include <grass/glocale.h>
  38. #include "gsget.h"
  39. #include "rowcol.h"
  40. #include "rgbpack.h"
  41. /* Hack to make NVIZ2.2 query functions.("What's Here" and "Look at")
  42. * to work.
  43. * Uses gs_los_intersect1() instead of gs_los_intersect().
  44. * Pierre de Mouveaux - 31 oct. 1999. p_de_mouveaux@hotmail.com.
  45. */
  46. #define NVIZ_HACK 1
  47. int gsd_getViewport(GLint *, GLint *);
  48. /* array of surface ids */
  49. static int Surf_ID[MAX_SURFS];
  50. static int Next_surf = 0;
  51. static int SDref_surf = 0;
  52. /* attributes array */
  53. static float Default_const[MAX_ATTS];
  54. static float Default_nulls[MAX_ATTS];
  55. /* largest dimension */
  56. static float Longdim;
  57. /* N, S, W, E */
  58. static float Region[4];
  59. static geoview Gv;
  60. static geodisplay Gd;
  61. static struct Cell_head wind;
  62. static int Buffermode;
  63. static int Numlights = 0;
  64. static int Modelshowing = 0;
  65. void void_func(void)
  66. {
  67. return;
  68. }
  69. /*!
  70. \brief Library initialization
  71. Get region settings - wind, Region (NSWE array)
  72. Compute scale
  73. */
  74. void GS_libinit(void)
  75. {
  76. static int first = 1;
  77. G_get_set_window(&wind);
  78. Region[0] = wind.north;
  79. Region[1] = wind.south;
  80. Region[2] = wind.west;
  81. Region[3] = wind.east;
  82. /* scale largest dimension to GS_UNIT_SIZE */
  83. if ((wind.east - wind.west) > (wind.north - wind.south)) {
  84. Longdim = (wind.east - wind.west);
  85. }
  86. else {
  87. Longdim = (wind.north - wind.south);
  88. }
  89. Gv.scale = GS_UNIT_SIZE / Longdim;
  90. Cxl_func = void_func;
  91. Swap_func = void_func;
  92. if (first) {
  93. gs_init();
  94. }
  95. first = 0;
  96. return;
  97. }
  98. /*!
  99. \brief Get largest dimension
  100. \param[out] dim dimension
  101. \return 1
  102. */
  103. int GS_get_longdim(float *dim)
  104. {
  105. *dim = Longdim;
  106. return (1);
  107. }
  108. /*!
  109. \brief Get 2D region extent
  110. \param[out] n,s,w,e extent values
  111. \return 1
  112. */
  113. int GS_get_region(float *n, float *s, float *w, float *e)
  114. {
  115. *n = Region[0];
  116. *s = Region[1];
  117. *w = Region[2];
  118. *e = Region[3];
  119. return (1);
  120. }
  121. /*!
  122. \brief Set attributes to default
  123. \param defs attributes array (dim MAX_ATTS)
  124. \param null_defs null attributes array (dim MAX_ATTS)
  125. */
  126. void GS_set_att_defaults(float *defs, float *null_defs)
  127. {
  128. int i;
  129. G_debug (3, "GS_set_att_defaults");
  130. for (i = 0; i < MAX_ATTS; i++) {
  131. Default_const[i] = defs[i];
  132. Default_nulls[i] = null_defs[i];
  133. }
  134. return;
  135. }
  136. /*!
  137. Check if surface exists
  138. \param id surface id
  139. \return 0 not found
  140. \return 1 found
  141. */
  142. int GS_surf_exists(int id)
  143. {
  144. int i, found = 0;
  145. G_debug(3, "GS_surf_exists");
  146. if (NULL == gs_get_surf(id)) {
  147. return (0);
  148. }
  149. for (i = 0; i < Next_surf && !found; i++) {
  150. if (Surf_ID[i] == id) {
  151. found = 1;
  152. }
  153. }
  154. return (found);
  155. }
  156. /*!
  157. \brief Add new surface
  158. Note that origin has 1/2 cell added to represent center of cells
  159. because library assumes that east - west = (cols - 1) * ew_res,
  160. since left and right columns are on the edges.
  161. \return surface id
  162. \return -1 on error (MAX_SURFS exceded)
  163. */
  164. int GS_new_surface(void)
  165. {
  166. geosurf *ns;
  167. G_debug(3, "GS_new_surface");
  168. if (Next_surf < MAX_SURFS) {
  169. ns = gs_get_new_surface();
  170. gs_init_surf(ns, wind.west + wind.ew_res / 2.,
  171. wind.south + wind.ns_res / 2., wind.rows, wind.cols,
  172. wind.ew_res, wind.ns_res);
  173. gs_set_defaults(ns, Default_const, Default_nulls);
  174. /* make default shine current */
  175. gs_set_att_src(ns, ATT_SHINE, CONST_ATT);
  176. Surf_ID[Next_surf] = ns->gsurf_id;
  177. ++Next_surf;
  178. return (ns->gsurf_id);
  179. }
  180. return (-1);
  181. }
  182. /*!
  183. \brief Add new light model
  184. \return light model id
  185. \return -1 on error (MAX_LIGHTS exceded)
  186. */
  187. int GS_new_light(void)
  188. {
  189. static int first = 1;
  190. int i;
  191. if (first) {
  192. first = 0;
  193. for (i = 0; i < MAX_LIGHTS; i++) {
  194. Gv.lights[i].position[X] = Gv.lights[i].position[Y] = 0.0;
  195. Gv.lights[i].position[Z] = 1.0;
  196. Gv.lights[i].position[W] = 0.0; /* infinite */
  197. Gv.lights[i].color[0] = Gv.lights[i].color[1] =
  198. Gv.lights[i].color[2] = 1.0;
  199. Gv.lights[i].ambient[0] = Gv.lights[i].ambient[1] =
  200. Gv.lights[i].ambient[2] = 0.2;
  201. Gv.lights[i].shine = 32.0;
  202. }
  203. gsd_init_lightmodel();
  204. }
  205. if (Numlights < MAX_LIGHTS) {
  206. gsd_deflight(Numlights + 1, &(Gv.lights[Numlights]));
  207. gsd_switchlight(Numlights + 1, 1);
  208. return (++Numlights);
  209. }
  210. return (-1);
  211. }
  212. /*!
  213. \brief Set light position
  214. \bug I think lights array doesnt match sgi_light array
  215. \param num light id (starts with 1?)
  216. \param xpos,ypos,zpos coordinates
  217. \param local ?
  218. */
  219. void GS_setlight_position(int num, float xpos, float ypos, float zpos,
  220. int local)
  221. {
  222. if (num) {
  223. num -= 1;
  224. if (num < Numlights) {
  225. Gv.lights[num].position[X] = xpos;
  226. Gv.lights[num].position[Y] = ypos;
  227. Gv.lights[num].position[Z] = zpos;
  228. Gv.lights[num].position[W] = (float) local;
  229. gsd_deflight(num + 1, &(Gv.lights[num]));
  230. }
  231. }
  232. return;
  233. }
  234. /*!
  235. \brief Get light position
  236. \param num light id (starts with 1?)
  237. \param[out] xpos,ypos,zpos coordinates
  238. \param[out] local ?
  239. */
  240. void GS_getlight_position(int num, float *xpos, float *ypos, float *zpos,
  241. int *local)
  242. {
  243. if (num) {
  244. num -= 1;
  245. if (num < Numlights) {
  246. *xpos = Gv.lights[num].position[X];
  247. *ypos = Gv.lights[num].position[Y];
  248. *zpos = Gv.lights[num].position[Z];
  249. *local = (int) Gv.lights[num].position[W];
  250. }
  251. }
  252. return;
  253. }
  254. /*!
  255. \brief Set light color
  256. \param num light id (starts with 1?)
  257. \param red,green,blue color values (from 0.0 to 1.0)
  258. */
  259. void GS_setlight_color(int num, float red, float green, float blue)
  260. {
  261. if (num) {
  262. num -= 1;
  263. if (num < Numlights) {
  264. Gv.lights[num].color[0] = red;
  265. Gv.lights[num].color[1] = green;
  266. Gv.lights[num].color[2] = blue;
  267. gsd_deflight(num + 1, &(Gv.lights[num]));
  268. }
  269. }
  270. return;
  271. }
  272. /*!
  273. \brief Get light color
  274. \param num light id (starts with 1?)
  275. \param[out] red,green,blue color values
  276. */
  277. void GS_getlight_color(int num, float *red, float *green, float *blue)
  278. {
  279. if (num) {
  280. num -= 1;
  281. if (num < Numlights) {
  282. *red = Gv.lights[num].color[0];
  283. *green = Gv.lights[num].color[1];
  284. *blue = Gv.lights[num].color[2];
  285. }
  286. }
  287. return;
  288. }
  289. /*!
  290. \brief Set light ambient
  291. Red, green, blue from 0.0 to 1.0
  292. \param num light id (starts with 1?)
  293. \param red,green,blue color values
  294. */
  295. void GS_setlight_ambient(int num, float red, float green, float blue)
  296. {
  297. if (num) {
  298. num -= 1;
  299. if (num < Numlights) {
  300. Gv.lights[num].ambient[0] = red;
  301. Gv.lights[num].ambient[1] = green;
  302. Gv.lights[num].ambient[2] = blue;
  303. gsd_deflight(num + 1, &(Gv.lights[num]));
  304. }
  305. }
  306. return;
  307. }
  308. /*!
  309. \brief Get light ambient
  310. \param num light id (starts with 1?)
  311. \param[out] red,green,blue color values
  312. */
  313. void GS_getlight_ambient(int num, float *red, float *green, float *blue)
  314. {
  315. if (num) {
  316. num -= 1;
  317. if (num < Numlights) {
  318. *red = Gv.lights[num].ambient[0];
  319. *green = Gv.lights[num].ambient[1];
  320. *blue = Gv.lights[num].ambient[2];
  321. }
  322. }
  323. return;
  324. }
  325. /*!
  326. \brief Switch off all lights
  327. */
  328. void GS_lights_off(void)
  329. {
  330. int i;
  331. for (i = 0; i < Numlights; i++) {
  332. gsd_switchlight(i + 1, 0);
  333. }
  334. return;
  335. }
  336. /*!
  337. \brief Switch on all lights
  338. */
  339. void GS_lights_on(void)
  340. {
  341. int i;
  342. for (i = 0; i < Numlights; i++) {
  343. gsd_switchlight(i + 1, 1);
  344. }
  345. return;
  346. }
  347. /*!
  348. \brief Switch on/off light
  349. \param num light id (starts with 1?)
  350. \param on non-zero for 'on' otherwise 'off'
  351. */
  352. void GS_switchlight(int num, int on)
  353. {
  354. if (num) {
  355. num -= 1;
  356. if (num < Numlights) {
  357. gsd_switchlight(num + 1, on);
  358. }
  359. }
  360. return;
  361. }
  362. /*!
  363. \brief Check if transparency is set
  364. \return 0 transparency not set
  365. \return 1 transparency is set
  366. */
  367. int GS_transp_is_set(void)
  368. {
  369. return (gs_att_is_set(NULL, ATT_TRANSP) || (FC_GREY == gsd_getfc()));
  370. }
  371. /*!
  372. \brief Retrieves coordinates for lighting model position, at center of view
  373. \param pos[out] coordinates
  374. */
  375. void GS_get_modelposition1(float pos[])
  376. {
  377. /* TODO: Still needs work to handle other cases */
  378. /* this is a quick hack to get lighting adjustments debugged */
  379. /*
  380. GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], center);
  381. GS_v3mult(center, 1000);
  382. GS_v3add(center, Gv.from_to[FROM]);
  383. */
  384. gs_get_datacenter(pos);
  385. gs_get_data_avg_zmax(&(pos[Z]));
  386. G_debug (1, "GS_get_modelposition1(): model position: %f %f %f",
  387. pos[X], pos[Y], pos[Z]);
  388. return;
  389. }
  390. /*!
  391. \brief Retrieves coordinates for lighting model position, at center of view
  392. Position at nearclip * 2: tried nearclip + siz, but since need to
  393. know position to calculate size, have two dependent variables
  394. (nearclip * 2) from eye.
  395. \param siz[out] size
  396. \param pos[out] coordinates (X, Y, Z)
  397. */
  398. void GS_get_modelposition(float *siz, float *pos)
  399. {
  400. float dist, near_h, dir[3];
  401. dist = 2. * Gd.nearclip;
  402. near_h = 2.0 * tan(4.0 * atan(1.) * Gv.fov / 3600.) * dist;
  403. *siz = near_h / 8.0;
  404. /* prevent clipping - would only happen if fov > ~127 degrees, at
  405. fov = 2.0 * atan(2.0) */
  406. if (*siz > Gd.nearclip) {
  407. *siz = Gd.nearclip;
  408. }
  409. GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir);
  410. pos[X] = Gv.from_to[FROM][X] + dir[X] * dist;
  411. pos[Y] = Gv.from_to[FROM][Y] + dir[Y] * dist;
  412. pos[Z] = Gv.from_to[FROM][Z] + dir[Z] * dist;
  413. return;
  414. }
  415. /*!
  416. \brief Set decoration, north arrow ??
  417. \todo scale used to calculate len of arrow still needs work
  418. needs go function that returns center / eye distance
  419. gsd_get_los function is not working correctly ??
  420. \param pt point value in true world coordinates (?)
  421. \param id surface id
  422. \param[out] pos2 output coordinates
  423. */
  424. void GS_set_Narrow(int *pt, int id, float *pos2)
  425. {
  426. geosurf *gs;
  427. float x, y, z;
  428. GLdouble modelMatrix[16], projMatrix[16];
  429. GLint viewport[4];
  430. if (GS_get_selected_point_on_surface(pt[X], pt[Y], &id, &x, &y, &z)) {
  431. gs = gs_get_surf(id);
  432. if (gs) {
  433. z = gs->zmax;
  434. pos2[X] = (float)x - gs->ox + gs->x_trans;
  435. pos2[Y] = (float)y - gs->oy + gs->y_trans;
  436. pos2[Z] = (float)z + gs->z_trans;
  437. return;
  438. }
  439. }
  440. else {
  441. gs = gs_get_surf(id);
  442. /* Need to get model matrix, etc
  443. * to run gluUnProject
  444. */
  445. gsd_pushmatrix();
  446. gsd_do_scale(1);
  447. glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
  448. glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
  449. glGetIntegerv(GL_VIEWPORT, viewport);
  450. if (gs) {
  451. GLdouble out_near[3], out_far[3];
  452. GLdouble factor;
  453. GLdouble out[3];
  454. z = (float)gs->zmax + gs->z_trans;
  455. gluUnProject((GLdouble)pt[X], (GLdouble)pt[Y], (GLdouble)0.,
  456. modelMatrix, projMatrix, viewport,
  457. &out_near[X], &out_near[Y], &out_near[Z]);
  458. gluUnProject((GLdouble)pt[X], (GLdouble)pt[Y], (GLdouble)1.,
  459. modelMatrix, projMatrix, viewport,
  460. &out_far[X], &out_far[Y], &out_far[Z]);
  461. glPopMatrix();
  462. factor = (out_near[Z]-z) / (out_near[Z]-out_far[Z]);
  463. out[X] = out_near[X]-((out_near[X]-out_far[X])*factor);
  464. out[Y] = out_near[Y]-((out_near[Y]-out_far[Y])*factor);
  465. out[Z] = z;
  466. pos2[X] = (float)out[X];
  467. pos2[Y] = (float)out[Y];
  468. pos2[Z] = (float)out[Z];
  469. return;
  470. }
  471. }
  472. return;
  473. }
  474. /*!
  475. \brief ADD
  476. \param id surface id
  477. \param pt point, X, Y value in true world coordinates
  478. */
  479. void GS_draw_X(int id, float *pt)
  480. {
  481. geosurf *gs;
  482. Point3 pos;
  483. float siz;
  484. if ((gs = gs_get_surf(id))) {
  485. GS_get_longdim(&siz);
  486. siz /= 200.;
  487. pos[X] = pt[X] - gs->ox;
  488. pos[Y] = pt[Y] - gs->oy;
  489. _viewcell_tri_interp(gs, pos);
  490. gsd_pushmatrix();
  491. gsd_do_scale(1);
  492. gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
  493. gsd_linewidth(1);
  494. if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) {
  495. pos[Z] = gs->att[ATT_TOPO].constant;
  496. gs = NULL; /* tells gpd_obj to use given Z val */
  497. }
  498. gpd_obj(gs, Gd.bgcol, siz, ST_GYRO, pos);
  499. gsd_flush();
  500. gsd_popmatrix();
  501. }
  502. return;
  503. }
  504. /*!
  505. \brief Draw line on surface
  506. \param id surface id
  507. \param x1,y1,x2,y2 line nodes
  508. */
  509. void GS_draw_line_onsurf(int id, float x1, float y1, float x2, float y2)
  510. {
  511. float p1[2], p2[2];
  512. geosurf *gs;
  513. if ((gs = gs_get_surf(id))) {
  514. p1[X] = x1 - gs->ox;
  515. p1[Y] = y1 - gs->oy;
  516. p2[X] = x2 - gs->ox;
  517. p2[Y] = y2 - gs->oy;
  518. gsd_pushmatrix();
  519. gsd_do_scale(1);
  520. gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
  521. gsd_linewidth(1);
  522. gsd_color_func(GS_default_draw_color());
  523. gsd_line_onsurf(gs, p1, p2);
  524. gsd_popmatrix();
  525. gsd_flush();
  526. }
  527. return;
  528. }
  529. /*!
  530. \brief Draw multiline on surface
  531. Like above but limits points in line to n or points found in segment,
  532. whichever is smaller.
  533. \param id surface id
  534. \param x1,y1,x2,y2 line nodes
  535. \param lasp ?
  536. \paran n ?
  537. \return number of points used
  538. */
  539. int GS_draw_nline_onsurf(int id, float x1, float y1, float x2, float y2,
  540. float *lasp, int n)
  541. {
  542. float p1[2], p2[2];
  543. geosurf *gs;
  544. int ret = 0;
  545. if ((gs = gs_get_surf(id))) {
  546. p1[X] = x1 - gs->ox;
  547. p1[Y] = y1 - gs->oy;
  548. p2[X] = x2 - gs->ox;
  549. p2[Y] = y2 - gs->oy;
  550. gsd_pushmatrix();
  551. gsd_do_scale(1);
  552. gsd_translate(gs->x_trans, gs->y_trans, gs->z_trans);
  553. gsd_linewidth(1);
  554. gsd_color_func(GS_default_draw_color());
  555. ret = gsd_nline_onsurf(gs, p1, p2, lasp, n);
  556. gsd_surf2real(gs, lasp);
  557. gsd_popmatrix();
  558. gsd_flush();
  559. }
  560. return (ret);
  561. }
  562. /*!
  563. \brief Draw flow-line on surace
  564. This is slow - should be moved to gs_ but GS_ good for testing
  565. and useful for app programmer
  566. \param id surface id
  567. \param x,y coordinates of flow-line
  568. */
  569. void GS_draw_flowline_at_xy(int id, float x, float y)
  570. {
  571. geosurf *gs;
  572. float nv[3], pdir[2], mult;
  573. float p1[2], p2[2], next[2];
  574. int i = 0;
  575. if ((gs = gs_get_surf(id))) {
  576. p1[X] = x;
  577. p1[Y] = y;
  578. /* multiply by 1.5 resolutions to ensure a crossing ? */
  579. mult = .1 * (VXRES(gs) > VYRES(gs) ? VXRES(gs) : VYRES(gs));
  580. GS_coordpair_repeats(p1, p1, 50);
  581. while (1 == GS_get_norm_at_xy(id, p1[X], p1[Y], nv)) {
  582. if (nv[Z] == 1.0) {
  583. if (pdir[X] == 0.0 && pdir[Y] == 0.0) {
  584. break;
  585. }
  586. p2[X] = p1[X] + (pdir[X] * mult);
  587. p2[Y] = p1[Y] + (pdir[Y] * mult);
  588. }
  589. else {
  590. /* use previous direction */
  591. GS_v2norm(nv);
  592. p2[X] = p1[X] + (nv[X] * mult);
  593. p2[Y] = p1[Y] + (nv[Y] * mult);
  594. pdir[X] = nv[X];
  595. pdir[Y] = nv[Y];
  596. }
  597. if (i > 2000) {
  598. break;
  599. }
  600. if (GS_coordpair_repeats(p1, p2, 0)) {
  601. break;
  602. }
  603. /* Think about this: */
  604. /* degenerate line means edge or level edge ? */
  605. /* next is filled with last point drawn */
  606. if (2 > GS_draw_nline_onsurf(id, p1[X], p1[Y],
  607. p2[X], p2[Y], next, 3)) {
  608. break;
  609. }
  610. p1[X] = next[X];
  611. p1[Y] = next[Y];
  612. }
  613. G_debug(3, "GS_draw_flowline_at_xy(): dir: %f %f",
  614. nv[X], nv[Y]);
  615. }
  616. return;
  617. }
  618. /*!
  619. \brief Draw fringe around data at selected corners
  620. \param id surface id
  621. \param clr ?
  622. \param elev elevation value
  623. \param where ?
  624. */
  625. void GS_draw_fringe(int id, unsigned long clr, float elev, int *where)
  626. {
  627. geosurf *gs;
  628. if ((gs = gs_get_surf(id)))
  629. gsd_display_fringe(gs, clr, elev, where);
  630. }
  631. /*!
  632. \brief Draw legend
  633. \todo add legend from list option
  634. make font loading more flexible
  635. \param name legend name
  636. \param fontbase font-base
  637. \param size ?
  638. \param flags legend flags
  639. \param range values range
  640. \param pt ?
  641. */
  642. int GS_draw_legend(char *name, GLuint fontbase, int size, int *flags,
  643. float *range, int *pt)
  644. {
  645. int list_no;
  646. list_no = gsd_put_legend(name, fontbase, size, flags, range, pt);
  647. return (list_no);
  648. }
  649. /*!
  650. \brief Draw pre-defined list
  651. Uses glFlush() to ensure all drawing is complete
  652. before returning
  653. \param list_id list id
  654. */
  655. void GS_draw_list(GLuint list_id)
  656. {
  657. gsd_calllist(list_id);
  658. glFlush();
  659. return;
  660. }
  661. /*!
  662. \brief Draw all glLists
  663. Uses glFlush() to ensure all drawing is complete
  664. before returning
  665. */
  666. void GS_draw_all_list(void)
  667. {
  668. gsd_calllists(0); /* not sure if 0 is right - MN */
  669. glFlush();
  670. return;
  671. }
  672. /*!
  673. \brief Delete pre-defined list
  674. \param list_id list id
  675. */
  676. void GS_delete_list(GLuint list_id)
  677. {
  678. gsd_deletelist(list_id, 1);
  679. return;
  680. }
  681. /*!
  682. \brief Draw lighting model
  683. */
  684. void GS_draw_lighting_model1(void)
  685. {
  686. static float center[3];
  687. float tcenter[3];
  688. if (!Modelshowing) {
  689. GS_get_modelposition1(center);
  690. }
  691. GS_v3eq(tcenter, center);
  692. gsd_zwritemask(0x0);
  693. gsd_backface(1);
  694. gsd_colormode(CM_AD);
  695. gsd_shademodel(DM_GOURAUD);
  696. gsd_pushmatrix();
  697. gsd_do_scale(1);
  698. if (Gv.vert_exag) {
  699. tcenter[Z] *= Gv.vert_exag;
  700. gsd_scale(1.0, 1.0, 1. / Gv.vert_exag);
  701. }
  702. gsd_drawsphere(tcenter, 0xDDDDDD, (float) (Longdim / 10.));
  703. gsd_popmatrix();
  704. Modelshowing = 1;
  705. gsd_backface(0);
  706. gsd_zwritemask(0xffffffff);
  707. return;
  708. }
  709. /*!
  710. \brief Draw lighting model
  711. Just turn off any cutting planes and draw it just outside near
  712. clipping plane, since lighting is infinite now
  713. */
  714. void GS_draw_lighting_model(void)
  715. {
  716. static float center[3], size;
  717. float tcenter[3], tsize;
  718. int i, wason[MAX_CPLANES];
  719. gsd_get_cplanes_state(wason);
  720. for (i = 0; i < MAX_CPLANES; i++) {
  721. if (wason[i]) {
  722. gsd_cplane_off(i);
  723. }
  724. }
  725. if (!Modelshowing) {
  726. GS_get_modelposition(&size, center);
  727. }
  728. GS_v3eq(tcenter, center);
  729. tsize = size;
  730. gsd_zwritemask(0x0);
  731. gsd_backface(1);
  732. gsd_colormode(CM_DIFFUSE);
  733. gsd_shademodel(DM_GOURAUD);
  734. gsd_pushmatrix();
  735. gsd_drawsphere(tcenter, 0xDDDDDD, tsize);
  736. gsd_popmatrix();
  737. Modelshowing = 1;
  738. gsd_backface(0);
  739. gsd_zwritemask(0xffffffff);
  740. for (i = 0; i < MAX_CPLANES; i++) {
  741. if (wason[i]) {
  742. gsd_cplane_on(i);
  743. }
  744. }
  745. gsd_flush();
  746. return;
  747. }
  748. /*!
  749. \brief Update current mask
  750. May be called to update total mask for a surface at convenient times
  751. instead of waiting until ready to redraw surface
  752. \param id surface id
  753. \return ?
  754. */
  755. int GS_update_curmask(int id)
  756. {
  757. geosurf *gs;
  758. gs = gs_get_surf(id);
  759. return (gs_update_curmask(gs));
  760. }
  761. /*!
  762. \brief Check if point is masked ?
  763. \param id surface id
  764. \param pt point
  765. \return 1 masked
  766. \return 0 not masked
  767. \return -1 on error, invalid surface id
  768. */
  769. int GS_is_masked(int id, float *pt)
  770. {
  771. geosurf *gs;
  772. Point3 tmp;
  773. if ((gs = gs_get_surf(id))) {
  774. tmp[X] = pt[X] - gs->ox;
  775. tmp[Y] = pt[Y] - gs->oy;
  776. return (gs_point_is_masked(gs, tmp));
  777. }
  778. return (-1);
  779. }
  780. /*!
  781. \brief Unset ?
  782. */
  783. void GS_unset_SDsurf(void)
  784. {
  785. gsdiff_set_SDref(NULL);
  786. SDref_surf = 0;
  787. return;
  788. }
  789. /*!
  790. \brief Set ?
  791. \param id surface id
  792. \return 1 on success
  793. \return 0 on error, invalid surface id
  794. */
  795. int GS_set_SDsurf(int id)
  796. {
  797. geosurf *gs;
  798. if ((gs = gs_get_surf(id))) {
  799. gsdiff_set_SDref(gs);
  800. SDref_surf = id;
  801. return (1);
  802. }
  803. return (0);
  804. }
  805. /*!
  806. \brief Set ?
  807. \param scale scale value
  808. \return 1
  809. */
  810. int GS_set_SDscale(float scale)
  811. {
  812. gsdiff_set_SDscale(scale);
  813. return (1);
  814. }
  815. /*!
  816. \brief Get ?
  817. \param[out] id ?
  818. \return 1 on success
  819. \return 0 on error
  820. */
  821. int GS_get_SDsurf(int *id)
  822. {
  823. geosurf *gs;
  824. if ((gs = gsdiff_get_SDref())) {
  825. *id = SDref_surf;
  826. return (1);
  827. }
  828. return (0);
  829. }
  830. /*!
  831. \brief Get ?
  832. \param[out] scale value
  833. \return 1
  834. */
  835. int GS_get_SDscale(float *scale)
  836. {
  837. *scale = gsdiff_get_SDscale();
  838. return (1);
  839. }
  840. /*!
  841. \brief Update normals
  842. \param id surface id
  843. \return ?
  844. */
  845. int GS_update_normals(int id)
  846. {
  847. geosurf *gs;
  848. gs = gs_get_surf(id);
  849. return (gs_calc_normals(gs));
  850. }
  851. /*!
  852. \brief Get attributes
  853. \param id surface id
  854. \param att
  855. \param[out] set
  856. \param[out] constant
  857. \param[out] mapname
  858. \return 1 on success
  859. \return -1 on error (invalid surface id)
  860. */
  861. int GS_get_att(int id, int att, int *set, float *constant, char *mapname)
  862. {
  863. int src;
  864. geosurf *gs;
  865. gs = gs_get_surf(id);
  866. if (gs) {
  867. if (-1 != (src = gs_get_att_src(gs, att))) {
  868. *set = src;
  869. if (src == CONST_ATT) {
  870. *constant = gs->att[att].constant;
  871. }
  872. else if (src == MAP_ATT) {
  873. strcpy(mapname, gsds_get_name(gs->att[att].hdata));
  874. }
  875. return (1);
  876. }
  877. return (-1);
  878. }
  879. return (-1);
  880. }
  881. #define CATSREADY
  882. #ifdef CATSREADY
  883. /*!
  884. \brief Print categories on given position
  885. prints "no data" or a description (i.e., "coniferous forest") to catstr
  886. Usually call after GS_get_selected_point_on_surface
  887. att_src must be MAP_ATT
  888. \param id surface id
  889. \param att
  890. \param catstr cat string (must be allocated, dim?)
  891. \param x,y real coordinates
  892. \return -1 if no category info or point outside of window
  893. \return 1 on success
  894. */
  895. int GS_get_cat_at_xy(int id, int att, char *catstr, float x, float y)
  896. {
  897. int offset, drow, dcol, vrow, vcol;
  898. float ftmp, pt[3];
  899. typbuff *buff;
  900. geosurf *gs;
  901. catstr[0] = '\0';
  902. gs = gs_get_surf(id);
  903. if (NULL == gs) {
  904. return (-1);
  905. }
  906. pt[X] = x;
  907. pt[Y] = y;
  908. gsd_real2surf(gs, pt);
  909. if (gs_point_is_masked(gs, pt)) {
  910. return (-1);
  911. }
  912. if (!in_vregion(gs, pt)) {
  913. return (-1);
  914. }
  915. if (MAP_ATT != gs_get_att_src(gs, att)) {
  916. sprintf(catstr, "no category info");
  917. return (-1);
  918. }
  919. buff = gs_get_att_typbuff(gs, att, 0);
  920. vrow = Y2VROW(gs, pt[Y]);
  921. vcol = X2VCOL(gs, pt[X]);
  922. drow = VROW2DROW(gs, vrow);
  923. dcol = VCOL2DCOL(gs, vcol);
  924. offset = DRC2OFF(gs, drow, dcol);
  925. if (GET_MAPATT(buff, offset, ftmp)) {
  926. return
  927. (Gs_get_cat_label
  928. (gsds_get_name(gs->att[att].hdata), drow, dcol, catstr));
  929. }
  930. sprintf(catstr, "no data");
  931. return (1);
  932. }
  933. /*!
  934. \brief Get surface normal at x,y (real coordinates)
  935. Usually call after GS_get_selected_point_on_surface()
  936. \param id surface id
  937. \param x,y real coordinates
  938. \param[out] nv surface normal
  939. \return -1 if point outside of window or masked
  940. \return 1 on success
  941. */
  942. int GS_get_norm_at_xy(int id, float x, float y, float *nv)
  943. {
  944. int offset, drow, dcol, vrow, vcol;
  945. float pt[3];
  946. geosurf *gs;
  947. gs = gs_get_surf(id);
  948. if (NULL == gs) {
  949. return (-1);
  950. }
  951. if (gs->norm_needupdate) {
  952. gs_calc_normals(gs);
  953. }
  954. pt[X] = x;
  955. pt[Y] = y;
  956. gsd_real2surf(gs, pt);
  957. if (gs_point_is_masked(gs, pt)) {
  958. return (-1);
  959. }
  960. if (!in_vregion(gs, pt)) {
  961. return (-1);
  962. }
  963. vrow = Y2VROW(gs, pt[Y]);
  964. vcol = X2VCOL(gs, pt[X]);
  965. drow = VROW2DROW(gs, vrow);
  966. dcol = VCOL2DCOL(gs, vcol);
  967. offset = DRC2OFF(gs, drow, dcol);
  968. if (gs->norms) {
  969. FNORM(gs->norms[offset], nv);
  970. }
  971. else {
  972. /* otherwise must be a constant */
  973. nv[0] = 0.0;
  974. nv[1] = 0.0;
  975. nv[2] = 1.0;
  976. }
  977. return (1);
  978. }
  979. /*!
  980. \brief Get RGB color at given point
  981. Colors are translated to rgb and returned as Rxxx Gxxx Bxxx
  982. Usually call after GS_get_selected_point_on_surface()
  983. Prints "NULL" or the value (i.e., "921.5") to valstr
  984. Usually call after GS_get_selected_point_on_surface()
  985. \param id surface id
  986. \param att
  987. \param[out] valstr value string (allocated, dim?)
  988. \param x,y real coordinates
  989. \return -1 if point outside of window or masked
  990. \return 1 on success
  991. */
  992. int GS_get_val_at_xy(int id, int att, char *valstr, float x, float y)
  993. {
  994. int offset, drow, dcol, vrow, vcol;
  995. float ftmp, pt[3];
  996. typbuff *buff;
  997. geosurf *gs;
  998. valstr = '\0';
  999. gs = gs_get_surf(id);
  1000. if (NULL == gs) {
  1001. return (-1);
  1002. }
  1003. pt[X] = x;
  1004. pt[Y] = y;
  1005. gsd_real2surf(gs, pt);
  1006. if (gs_point_is_masked(gs, pt)) {
  1007. return (-1);
  1008. }
  1009. if (!in_vregion(gs, pt)) {
  1010. return (-1);
  1011. }
  1012. if (CONST_ATT == gs_get_att_src(gs, att)) {
  1013. if (att == ATT_COLOR) {
  1014. int r, g, b, i;
  1015. i = gs->att[att].constant;
  1016. sprintf(valstr, "R%d G%d B%d",
  1017. INT_TO_RED(i, r), INT_TO_GRN(i, g), INT_TO_BLU(i, b));
  1018. }
  1019. else {
  1020. sprintf(valstr, "%f", gs->att[att].constant);
  1021. }
  1022. return (1);
  1023. }
  1024. else if (MAP_ATT != gs_get_att_src(gs, att)) {
  1025. return (-1);
  1026. }
  1027. buff = gs_get_att_typbuff(gs, att, 0);
  1028. vrow = Y2VROW(gs, pt[Y]);
  1029. vcol = X2VCOL(gs, pt[X]);
  1030. drow = VROW2DROW(gs, vrow);
  1031. dcol = VCOL2DCOL(gs, vcol);
  1032. offset = DRC2OFF(gs, drow, dcol);
  1033. if (GET_MAPATT(buff, offset, ftmp)) {
  1034. if (att == ATT_COLOR) {
  1035. int r, g, b, i;
  1036. i = gs_mapcolor(gs_get_att_typbuff(gs, ATT_COLOR, 0),
  1037. &(gs->att[ATT_COLOR]), offset);
  1038. sprintf(valstr, "R%d G%d B%d",
  1039. INT_TO_RED(i, r), INT_TO_GRN(i, g), INT_TO_BLU(i, b));
  1040. }
  1041. else {
  1042. sprintf(valstr, "%f", ftmp);
  1043. }
  1044. return (1);
  1045. }
  1046. sprintf(valstr, "NULL");
  1047. return (1);
  1048. }
  1049. #endif
  1050. /*!
  1051. \brief Unset attribute
  1052. \param id surface id
  1053. \param att attribute id
  1054. \return ?
  1055. */
  1056. int GS_unset_att(int id, int att)
  1057. {
  1058. geosurf *gs;
  1059. gs = gs_get_surf(id);
  1060. gs->mask_needupdate = 1;
  1061. return (gs_set_att_src(gs, att, NOTSET_ATT));
  1062. }
  1063. /*!
  1064. \brief Set attribute constant
  1065. \param id surface id
  1066. \param att attribute id
  1067. \param constant value
  1068. \return ?
  1069. */
  1070. int GS_set_att_const(int id, int att, float constant)
  1071. {
  1072. geosurf *gs;
  1073. int ret;
  1074. gs = gs_get_surf(id);
  1075. ret = (gs_set_att_const(gs, att, constant));
  1076. Gs_update_attrange(gs, att);
  1077. return (ret);
  1078. }
  1079. /*!
  1080. \brief Set mask mode
  1081. Mask attribute special: constant is set to indicate invert or no
  1082. \param id surface id
  1083. \param mode id
  1084. \return mode id
  1085. \return -1 on error (invalid surface id)
  1086. */
  1087. int GS_set_maskmode(int id, int mode)
  1088. {
  1089. geosurf *gs;
  1090. gs = gs_get_surf(id);
  1091. if (gs) {
  1092. gs->att[ATT_MASK].constant = mode;
  1093. gs->mask_needupdate = 1;
  1094. return (mode);
  1095. }
  1096. return (-1);
  1097. }
  1098. /*!
  1099. \brief Get mask mode
  1100. \param id surface id
  1101. \param[out] mode id
  1102. \return 1 on success
  1103. \return -1 on error (invalid surface id)
  1104. */
  1105. int GS_get_maskmode(int id, int *mode)
  1106. {
  1107. geosurf *gs;
  1108. gs = gs_get_surf(id);
  1109. if (gs) {
  1110. *mode = gs->att[ATT_MASK].constant;
  1111. return (1);
  1112. }
  1113. return (-1);
  1114. }
  1115. /*!
  1116. \brief Set client data
  1117. \param id surface id
  1118. \param clientd ?
  1119. \return 1 on success
  1120. \return -1 on error (invalid surface id)
  1121. */
  1122. int GS_Set_ClientData(int id, void *clientd)
  1123. {
  1124. geosurf *gs;
  1125. gs = gs_get_surf(id);
  1126. if (gs) {
  1127. gs->clientdata = clientd;
  1128. return (1);
  1129. }
  1130. return (-1);
  1131. }
  1132. /*!
  1133. \brief Get client data
  1134. \param id surface id
  1135. \return pointer to client data
  1136. \return NULL on error
  1137. */
  1138. void *GS_Get_ClientData(int id)
  1139. {
  1140. geosurf *gs;
  1141. gs = gs_get_surf(id);
  1142. if (gs) {
  1143. return (gs->clientdata);
  1144. }
  1145. return (NULL);
  1146. }
  1147. /*!
  1148. \brief Get number of surfaces
  1149. \return number of surfaces
  1150. */
  1151. int GS_num_surfs(void)
  1152. {
  1153. return (gs_num_surfaces());
  1154. }
  1155. /*!
  1156. \brief Get surface list
  1157. Must be freed when not neeed!
  1158. \param[out] numsurf number of available surfaces
  1159. \return pointer to surface array
  1160. \return NULL on error
  1161. */
  1162. int *GS_get_surf_list(int *numsurfs)
  1163. {
  1164. int i, *ret;
  1165. *numsurfs = Next_surf;
  1166. if (Next_surf) {
  1167. ret = (int *) G_malloc(Next_surf * sizeof(int));
  1168. for (i = 0; i < Next_surf; i++) {
  1169. ret[i] = Surf_ID[i];
  1170. }
  1171. return (ret);
  1172. }
  1173. return (NULL);
  1174. }
  1175. /*!
  1176. \brief Delete surface
  1177. \param id surface id
  1178. \return 1 on success
  1179. \return -1 on error
  1180. */
  1181. int GS_delete_surface(int id)
  1182. {
  1183. int i, j, found = 0;
  1184. G_debug(3, "GS_delete_surface");
  1185. if (GS_surf_exists(id)) {
  1186. gs_delete_surf(id);
  1187. for (i = 0; i < Next_surf && !found; i++) {
  1188. if (Surf_ID[i] == id) {
  1189. found = 1;
  1190. for (j = i; j < Next_surf; j++) {
  1191. Surf_ID[j] = Surf_ID[j + 1];
  1192. }
  1193. }
  1194. }
  1195. gv_update_drapesurfs();
  1196. if (found) {
  1197. --Next_surf;
  1198. return (1);
  1199. }
  1200. }
  1201. return (-1);
  1202. }
  1203. /*!
  1204. \brief Load attribute map
  1205. \param id surface id
  1206. \param filename filename
  1207. \param att attribute id
  1208. \return -1 on error (invalid surface id)
  1209. \return ?
  1210. */
  1211. int GS_load_att_map(int id, char *filename, int att)
  1212. {
  1213. geosurf *gs;
  1214. unsigned int changed;
  1215. unsigned int atty;
  1216. char *mapset;
  1217. struct Cell_head rast_head;
  1218. int reuse = 0, begin, hdata, ret, neg = 0, has_null = 0;
  1219. typbuff *tbuff;
  1220. G_debug (3, "GS_load_att_map(): att_map: %s", filename);
  1221. gs = gs_get_surf(id);
  1222. if (NULL == gs) {
  1223. return (-1);
  1224. }
  1225. gs->mask_needupdate = (ATT_MASK == att || ATT_TOPO == att ||
  1226. (gs->nz_topo && ATT_TOPO == att) ||
  1227. (gs->nz_color && ATT_COLOR == att));
  1228. gs_set_att_src(gs, att, MAP_ATT);
  1229. /* Check against maps already loaded in memory */
  1230. /* if to be color attribute:
  1231. - if packed color for another surface, OK to reuse
  1232. - if unchanged, ok to reuse IF it's of type char (will have lookup)
  1233. */
  1234. begin = hdata = 1;
  1235. /* Get MAPSET to ensure names are fully qualified */
  1236. mapset = G_find_cell2(filename, "");
  1237. if (mapset == NULL) {
  1238. /* Check for valid filename */
  1239. G_warning ("Raster map <%s> not found",
  1240. filename);
  1241. return -1;
  1242. }
  1243. filename = G_fully_qualified_name(filename, mapset);
  1244. /* Check to see if map is in Region */
  1245. G_get_cellhd(filename, mapset, &rast_head);
  1246. if (rast_head.north <= wind.south ||
  1247. rast_head.south >= wind.north ||
  1248. rast_head.east <= wind.west ||
  1249. rast_head.west >= wind.east)
  1250. {
  1251. G_fatal_error(_("Raster map <%s> is outside of current region. Load failed."),
  1252. filename);
  1253. }
  1254. while (!reuse && (0 < hdata)) {
  1255. changed = CF_COLOR_PACKED;
  1256. atty = ATTY_FLOAT | ATTY_CHAR | ATTY_INT | ATTY_SHORT | ATTY_MASK;
  1257. if (0 < (hdata = gsds_findh(filename, &changed, &atty, begin))) {
  1258. G_debug(3, "GS_load_att_map(): %s already has data handle %d.CF=%x",
  1259. filename, hdata, changed);
  1260. /* handle found */
  1261. if (ATT_COLOR == att) {
  1262. if ((changed == CF_COLOR_PACKED) ||
  1263. (!changed && atty == ATTY_CHAR)) {
  1264. reuse = 1;
  1265. }
  1266. }
  1267. else if (atty == ATTY_MASK && att != ATT_MASK) {
  1268. reuse = 0;
  1269. /* should also free mask data & share new - but need backward
  1270. reference? */
  1271. }
  1272. else if (!changed) {
  1273. reuse = 1;
  1274. }
  1275. }
  1276. begin = 0;
  1277. }
  1278. if (reuse) {
  1279. gs->att[att].hdata = hdata;
  1280. gs_set_att_type(gs, att, atty); /* ?? */
  1281. /* free lookup & set to NULL! */
  1282. if (atty == ATTY_INT) {
  1283. if (gs->att[att].lookup) {
  1284. free(gs->att[att].lookup);
  1285. gs->att[att].lookup = NULL;
  1286. }
  1287. }
  1288. /* TODO: FIX THIS stuff with lookup sharing! */
  1289. G_debug(3, "GS_load_att_map(): %s is being reused. hdata=%d",
  1290. filename, hdata);
  1291. }
  1292. else {
  1293. G_debug(3, "GS_load_att_map(): %s not loaded in correct form - loading now",
  1294. filename);
  1295. /* not loaded - need to get new dataset handle */
  1296. gs->att[att].hdata = gsds_newh(filename);
  1297. tbuff = gs_get_att_typbuff(gs, att, 1);
  1298. /* TODO: Provide mechanism for loading certain attributes at
  1299. specified sizes, allow to scale or cap, or scale non-zero */
  1300. if (ATT_MASK == att) {
  1301. atty = ATTY_MASK;
  1302. }
  1303. else {
  1304. atty = Gs_numtype(filename, &neg);
  1305. filename = G_fully_qualified_name(filename, mapset);
  1306. }
  1307. #ifdef MAYBE_LATER
  1308. if (att == ATT_COLOR && atty == ATTY_SHORT) {
  1309. atty = (neg ? ATTY_INT : ATTY_SHORT);
  1310. }
  1311. #endif
  1312. if (att == ATT_COLOR && atty == ATTY_SHORT) {
  1313. atty = ATTY_INT;
  1314. }
  1315. if (0 > gs_malloc_att_buff(gs, att, ATTY_NULL)) {
  1316. G_fatal_error (_("GS_load_att_map(): Out of memory. Unable to load map"));
  1317. }
  1318. switch (atty) {
  1319. case ATTY_MASK:
  1320. if (0 > gs_malloc_att_buff(gs, att, ATTY_MASK)) {
  1321. G_fatal_error (_("GS_load_att_map(): Out of memory. Unable to load map"));
  1322. }
  1323. ret = Gs_loadmap_as_bitmap(&wind, filename, tbuff->bm);
  1324. filename = G_fully_qualified_name(filename, mapset);
  1325. break;
  1326. case ATTY_CHAR:
  1327. if (0 > gs_malloc_att_buff(gs, att, ATTY_CHAR)) {
  1328. G_fatal_error (_("GS_load_att_map(): Out of memory. Unable to load map"));
  1329. }
  1330. ret = Gs_loadmap_as_char(&wind, filename, tbuff->cb,
  1331. tbuff->nm, &has_null);
  1332. filename = G_fully_qualified_name(filename, mapset);
  1333. break;
  1334. case ATTY_SHORT:
  1335. if (0 > gs_malloc_att_buff(gs, att, ATTY_SHORT)) {
  1336. G_fatal_error (_("GS_load_att_map(): Out of memory. Unable to load map"));
  1337. }
  1338. ret = Gs_loadmap_as_short(&wind, filename, tbuff->sb,
  1339. tbuff->nm, &has_null);
  1340. filename = G_fully_qualified_name(filename, mapset);
  1341. break;
  1342. case ATTY_FLOAT:
  1343. if (0 > gs_malloc_att_buff(gs, att, ATTY_FLOAT)) {
  1344. G_fatal_error (_("GS_load_att_map(): Out of memory. Unable to load map"));
  1345. }
  1346. ret = Gs_loadmap_as_float(&wind, filename, tbuff->fb,
  1347. tbuff->nm, &has_null);
  1348. filename = G_fully_qualified_name(filename, mapset);
  1349. G_debug(3, "HAS-NULL = %d", has_null);
  1350. break;
  1351. case ATTY_INT:
  1352. default:
  1353. if (0 > gs_malloc_att_buff(gs, att, ATTY_INT)) {
  1354. G_fatal_error (_("GS_load_att_map(): Out of memory. Unable to load map"));
  1355. }
  1356. ret = Gs_loadmap_as_int(&wind, filename, tbuff->ib,
  1357. tbuff->nm, &has_null);
  1358. filename = G_fully_qualified_name(filename, mapset);
  1359. break;
  1360. } /* Done with switch */
  1361. if (ret == -1) {
  1362. gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL);
  1363. return (-1);
  1364. }
  1365. G_debug(3, "HAS-NULL = %d", has_null);
  1366. if (!has_null) {
  1367. gsds_free_data_buff(gs->att[att].hdata, ATTY_NULL);
  1368. }
  1369. else {
  1370. gs_update_curmask(gs);
  1371. }
  1372. } /* end if not reuse */
  1373. if (ATT_COLOR == att) {
  1374. #ifdef MAYBE_LATER
  1375. if (ATTY_INT == atty) {
  1376. Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols);
  1377. gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
  1378. gs->att[att].lookup = NULL;
  1379. filename = G_fully_qualified_name(filename, mapset);
  1380. }
  1381. else {
  1382. gs_malloc_lookup(gs, att);
  1383. Gs_build_lookup(filename, gs->att[att].lookup);
  1384. filename = G_fully_qualified_name(filename, mapset);
  1385. }
  1386. #else
  1387. if (ATTY_CHAR == atty) {
  1388. if (!gs->att[att].lookup) {
  1389. /* might already exist if reusing */
  1390. gs_malloc_lookup(gs, att);
  1391. Gs_build_256lookup(filename, gs->att[att].lookup);
  1392. filename = G_fully_qualified_name(filename, mapset);
  1393. }
  1394. }
  1395. else if (ATTY_FLOAT == atty) {
  1396. if (!reuse) {
  1397. if (0 > gs_malloc_att_buff(gs, att, ATTY_INT)) {
  1398. G_fatal_error (_("GS_load_att_map(): Out of memory. Unable to load map"));
  1399. }
  1400. Gs_pack_colors_float(filename, tbuff->fb, tbuff->ib,
  1401. gs->rows, gs->cols);
  1402. gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
  1403. gsds_free_data_buff(gs->att[att].hdata, ATTY_FLOAT);
  1404. gs->att[att].lookup = NULL;
  1405. filename = G_fully_qualified_name(filename, mapset);
  1406. }
  1407. }
  1408. else {
  1409. if (!reuse) {
  1410. Gs_pack_colors(filename, tbuff->ib, gs->rows, gs->cols);
  1411. gsds_set_changed(gs->att[att].hdata, CF_COLOR_PACKED);
  1412. gs->att[att].lookup = NULL;
  1413. filename = G_fully_qualified_name(filename, mapset);
  1414. }
  1415. }
  1416. #endif
  1417. }
  1418. if (ATT_TOPO == att) {
  1419. gs_init_normbuff(gs);
  1420. /* S_DIFF: should also check here to see if this surface is a
  1421. reference surface for scaled differences, if so update references
  1422. to it */
  1423. }
  1424. if (ret < 0) {
  1425. G_warning (_("Loading failed"));
  1426. }
  1427. if (-1 == Gs_update_attrange(gs, att)) {
  1428. G_warning(_("Error finding range"));
  1429. }
  1430. G_debug (3, "Range Updated: %f %f",
  1431. gs->zmin, gs->zmax);
  1432. return (ret);
  1433. }
  1434. /*!
  1435. \brief Draw surface
  1436. \param id surface id
  1437. */
  1438. void GS_draw_surf(int id)
  1439. {
  1440. geosurf *gs;
  1441. G_debug(3, "GS_draw_surf");
  1442. gs = gs_get_surf(id);
  1443. if (gs) {
  1444. gsd_shademodel(gs->draw_mode & DM_GOURAUD);
  1445. if (gs->draw_mode & DM_POLY) {
  1446. gsd_surf(gs);
  1447. }
  1448. if (gs->draw_mode & DM_WIRE) {
  1449. gsd_wire_surf(gs);
  1450. }
  1451. /* TODO: write wire/poly draw routines */
  1452. if (gs->draw_mode & DM_WIRE_POLY) {
  1453. gsd_surf(gs);
  1454. gsd_wire_surf(gs);
  1455. }
  1456. }
  1457. return;
  1458. }
  1459. /*!
  1460. \brief Draw wire
  1461. Overrides draw_mode for fast display
  1462. \param id surface id
  1463. */
  1464. void GS_draw_wire(int id)
  1465. {
  1466. geosurf *gs;
  1467. G_debug(3, "GS_draw_wire");
  1468. gs = gs_get_surf(id);
  1469. if (gs) {
  1470. gsd_wire_surf(gs);
  1471. }
  1472. return;
  1473. }
  1474. /*!
  1475. \brief Draw all wires
  1476. Overrides draw_mode for fast display
  1477. */
  1478. void GS_alldraw_wire(void)
  1479. {
  1480. geosurf *gs;
  1481. int i;
  1482. for (i = 0; i < Next_surf; i++) {
  1483. if ((gs = gs_get_surf(Surf_ID[i]))) {
  1484. gsd_wire_surf(gs);
  1485. }
  1486. }
  1487. return;
  1488. }
  1489. /*!
  1490. \brief Draw all surfaces
  1491. */
  1492. void GS_alldraw_surf(void)
  1493. {
  1494. int i;
  1495. for (i = 0; i < Next_surf; i++) {
  1496. GS_draw_surf(Surf_ID[i]);
  1497. }
  1498. return;
  1499. }
  1500. /*!
  1501. \brief Set Z exag for surface
  1502. \param id surface id
  1503. \param exag z-exag value
  1504. */
  1505. void GS_set_exag(int id, float exag)
  1506. {
  1507. geosurf *gs;
  1508. G_debug(3, "GS_set_exag");
  1509. gs = gs_get_surf(id);
  1510. if (gs) {
  1511. if (gs->z_exag != exag) {
  1512. gs->norm_needupdate = 1;
  1513. }
  1514. gs->z_exag = exag;
  1515. }
  1516. return;
  1517. }
  1518. /*!
  1519. \brief Set global z-exag value
  1520. \param exag exag value to be set up
  1521. */
  1522. void GS_set_global_exag(float exag)
  1523. {
  1524. G_debug(3, "GS_set_global_exag");
  1525. Gv.vert_exag = exag;
  1526. /* GL_NORMALIZE */
  1527. /* Only need to update norms gs_norms.c
  1528. * if exag is used in norm equation which
  1529. * it is not! If GL_NORMALIZE is disabled
  1530. * will need to include.
  1531. gs_setall_norm_needupdate();
  1532. */
  1533. return;
  1534. }
  1535. /*!
  1536. \brief Get global z-exag value
  1537. \return value
  1538. */
  1539. float GS_global_exag(void)
  1540. {
  1541. G_debug(3, "GS_global_exag");
  1542. return (Gv.vert_exag);
  1543. }
  1544. /*!
  1545. \brief Set wire color
  1546. \todo error-handling
  1547. \param id surface id
  1548. \param colr color value
  1549. */
  1550. void GS_set_wire_color(int id, int colr)
  1551. {
  1552. geosurf *gs;
  1553. G_debug(3, "GS_set_wire_color");
  1554. gs = gs_get_surf(id);
  1555. if (gs) {
  1556. gs->wire_color = colr;
  1557. }
  1558. return;
  1559. }
  1560. /*!
  1561. \brief Get wire color
  1562. \param id surface id
  1563. \param[out] colr color value
  1564. \return 1 on success
  1565. \return -1 on error
  1566. */
  1567. int GS_get_wire_color(int id, int *colr)
  1568. {
  1569. geosurf *gs;
  1570. gs = gs_get_surf(id);
  1571. if (gs) {
  1572. *colr = gs->wire_color;
  1573. return (1);
  1574. }
  1575. return (-1);
  1576. }
  1577. /*!
  1578. \brief Set all draw-modes
  1579. \param mode mode id
  1580. \return 0 on success
  1581. \return -1 on error
  1582. */
  1583. int GS_setall_drawmode(int mode)
  1584. {
  1585. int i;
  1586. for (i = 0; i < Next_surf; i++) {
  1587. if (0 != GS_set_drawmode(Surf_ID[i], mode)) {
  1588. return (-1);
  1589. }
  1590. }
  1591. return (0);
  1592. }
  1593. /*!
  1594. \brief Set draw mode
  1595. \param id surface id
  1596. \param mode mode id
  1597. \return 0 on success
  1598. \return -1 on error (invalid surface id)
  1599. */
  1600. int GS_set_drawmode(int id, int mode)
  1601. {
  1602. geosurf *gs;
  1603. G_debug(3, "GS_set_drawmode");
  1604. gs = gs_get_surf(id);
  1605. if (gs) {
  1606. gs->draw_mode = mode;
  1607. return (0);
  1608. }
  1609. return (-1);
  1610. }
  1611. /*!
  1612. \brief Get draw mode
  1613. \param id surface id
  1614. \param[out] mode mode id
  1615. \return 1 on success
  1616. \return -1 on error (invalid surface id)
  1617. */
  1618. int GS_get_drawmode(int id, int *mode)
  1619. {
  1620. geosurf *gs;
  1621. gs = gs_get_surf(id);
  1622. if (gs) {
  1623. *mode = gs->draw_mode;
  1624. return (1);
  1625. }
  1626. return (-1);
  1627. }
  1628. /*!
  1629. \brief Set no-zero ?
  1630. \param id surface id
  1631. \param att attribute id
  1632. \param mode mode id
  1633. */
  1634. void GS_set_nozero(int id, int att, int mode)
  1635. {
  1636. geosurf *gs;
  1637. G_debug(3, "GS_set_nozero");
  1638. gs = gs_get_surf(id);
  1639. if (gs) {
  1640. if (att == ATT_TOPO) {
  1641. gs->nz_topo = mode;
  1642. gs->mask_needupdate = 1;
  1643. }
  1644. if (att == ATT_COLOR) {
  1645. gs->nz_color = mode;
  1646. gs->mask_needupdate = 1;
  1647. }
  1648. }
  1649. return;
  1650. }
  1651. /*!
  1652. \brief Get no-zero ?
  1653. \param id surface id
  1654. \param att attribute id
  1655. \param[out] mode mode id
  1656. \return -1 on error (invalid surface id)
  1657. \return 1 on success
  1658. */
  1659. int GS_get_nozero(int id, int att, int *mode)
  1660. {
  1661. geosurf *gs;
  1662. G_debug(3, "GS_set_nozero");
  1663. gs = gs_get_surf(id);
  1664. if (gs) {
  1665. if (att == ATT_TOPO) {
  1666. *mode = gs->nz_topo;
  1667. }
  1668. else if (att == ATT_COLOR) {
  1669. *mode = gs->nz_color;
  1670. }
  1671. else {
  1672. return (-1);
  1673. }
  1674. return (1);
  1675. }
  1676. return (-1);
  1677. }
  1678. /*!
  1679. \brief Set all draw resolutions
  1680. \param xres,yres x/y resolution value
  1681. \param xwire,ywire x/y wire value
  1682. \return 0 on success
  1683. \return -1 on error
  1684. */
  1685. int GS_setall_drawres(int xres, int yres, int xwire, int ywire)
  1686. {
  1687. int i;
  1688. for (i = 0; i < Next_surf; i++) {
  1689. if (0 != GS_set_drawres(Surf_ID[i], xres, yres, xwire, ywire)) {
  1690. return (-1);
  1691. }
  1692. }
  1693. return (0);
  1694. }
  1695. /*!
  1696. \brief Set draw resolution for surface
  1697. \param id surface id
  1698. \param xres,yres x/y resolution value
  1699. \param xwire,ywire x/y wire value
  1700. \return -1 on error
  1701. \return 0 on success
  1702. */
  1703. int GS_set_drawres(int id, int xres, int yres, int xwire, int ywire)
  1704. {
  1705. geosurf *gs;
  1706. G_debug(3, "GS_set_drawres");
  1707. if (xres < 1 || yres < 1 || xwire < 1 || ywire < 1) {
  1708. return (-1);
  1709. }
  1710. gs = gs_get_surf(id);
  1711. if (gs) {
  1712. if (gs->x_mod != xres || gs->y_mod != yres) {
  1713. gs->norm_needupdate = 1;
  1714. }
  1715. gs->x_mod = xres;
  1716. gs->y_mod = yres;
  1717. gs->x_modw = xwire;
  1718. gs->y_modw = ywire;
  1719. }
  1720. return (0);
  1721. }
  1722. /*!
  1723. \brief Get draw resolution of surface
  1724. \param id surface id
  1725. \param[out] xres,yres x/y resolution value
  1726. \param[out] xwire,ywire x/y wire value
  1727. */
  1728. void GS_get_drawres(int id, int *xres, int *yres, int *xwire, int *ywire)
  1729. {
  1730. geosurf *gs;
  1731. G_debug(3, "GS_get_drawres");
  1732. gs = gs_get_surf(id);
  1733. if (gs) {
  1734. *xres = gs->x_mod;
  1735. *yres = gs->y_mod;
  1736. *xwire = gs->x_modw;
  1737. *ywire = gs->y_modw;
  1738. }
  1739. return;
  1740. }
  1741. /*!
  1742. \brief Get dimension of surface
  1743. \param id surface id
  1744. \param[out] rows,cols number of rows/cols
  1745. */
  1746. void GS_get_dims(int id, int *rows, int *cols)
  1747. {
  1748. geosurf *gs;
  1749. G_debug(3, "GS_get_dims");
  1750. gs = gs_get_surf(id);
  1751. if (gs) {
  1752. *rows = gs->rows;
  1753. *cols = gs->cols;
  1754. }
  1755. return;
  1756. }
  1757. /*!
  1758. \brief Get exag-value guess
  1759. Use no_zero range because if zero IS data, then range won't be that
  1760. much off (it's just a GUESS, after all), but if zero is NO data, could
  1761. drastically affect guess
  1762. \param id surface id
  1763. \param[out] exag exag value
  1764. \return 1 on success
  1765. \return -1 on error
  1766. */
  1767. int GS_get_exag_guess(int id, float *exag)
  1768. {
  1769. geosurf *gs;
  1770. float guess;
  1771. gs = gs_get_surf(id);
  1772. guess = 1.0;
  1773. /* if gs is type const return guess = 1.0 */
  1774. if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO))
  1775. {
  1776. return(1);
  1777. }
  1778. if (gs) {
  1779. if (gs->zrange_nz == 0.0) {
  1780. *exag = 0.0;
  1781. return (1);
  1782. }
  1783. G_debug (3, "GS_get_exag_guess(): %f %f",
  1784. gs->zrange_nz, Longdim);
  1785. while (gs->zrange_nz * guess / Longdim >= .25) {
  1786. guess *= .1;
  1787. G_debug (3, "GS_get_exag_guess(): %f",
  1788. guess);
  1789. }
  1790. while (gs->zrange_nz * guess / Longdim < .025) {
  1791. guess *= 10.;
  1792. G_debug (3, "GS_get_exag_guess(): %f",
  1793. guess);
  1794. }
  1795. *exag = guess;
  1796. return (1);
  1797. }
  1798. return (-1);
  1799. }
  1800. /*!
  1801. Get Z extents for all loaded surfaces
  1802. Treating zeros as "no data"
  1803. \param[out] min min value
  1804. \param[out] max max value
  1805. */
  1806. void GS_get_zrange_nz(float *min, float *max)
  1807. {
  1808. int i, first = 1;
  1809. geosurf *gs;
  1810. for (i = 0; i < Next_surf; i++) {
  1811. if ((gs = gs_get_surf(Surf_ID[i]))) {
  1812. if (first) {
  1813. first = 0;
  1814. *min = gs->zmin_nz;
  1815. *max = gs->zmax_nz;
  1816. }
  1817. if (gs->zmin_nz < *min) {
  1818. *min = gs->zmin_nz;
  1819. }
  1820. if (gs->zmax_nz > *max) {
  1821. *max = gs->zmax_nz;
  1822. }
  1823. }
  1824. }
  1825. return;
  1826. }
  1827. /*!
  1828. \brief Set trans ?
  1829. \param id surface id
  1830. \param xtrans,ytrans,ztrans real trans coordinates
  1831. */
  1832. void GS_set_trans(int id, float xtrans, float ytrans, float ztrans)
  1833. {
  1834. geosurf *gs;
  1835. G_debug(3, "GS_set_trans");
  1836. gs = gs_get_surf(id);
  1837. if (gs) {
  1838. gs->x_trans = xtrans;
  1839. gs->y_trans = ytrans;
  1840. gs->z_trans = ztrans;
  1841. }
  1842. return;
  1843. }
  1844. /*!
  1845. \brief Get trans ?
  1846. \param id surface id
  1847. \param[out] xtrans,ytrans,ztrans real trans coordinates
  1848. */
  1849. void GS_get_trans(int id, float *xtrans, float *ytrans, float *ztrans)
  1850. {
  1851. geosurf *gs;
  1852. G_debug(3, "GS_get_trans");
  1853. gs = gs_get_surf(id);
  1854. if (gs) {
  1855. *xtrans = gs->x_trans;
  1856. *ytrans = gs->y_trans;
  1857. *ztrans = gs->z_trans;
  1858. }
  1859. return;
  1860. }
  1861. /*!
  1862. \brief Get default draw color
  1863. \return color value
  1864. */
  1865. unsigned int GS_default_draw_color(void)
  1866. {
  1867. G_debug(3, "GS_default_draw_color");
  1868. return ((unsigned int) Gd.bgcol);
  1869. }
  1870. /*!
  1871. \brief Get background color
  1872. \return color value
  1873. */
  1874. unsigned int GS_background_color(void)
  1875. {
  1876. return ((unsigned int) Gd.bgcol);
  1877. }
  1878. /*!
  1879. \brief Sets which buffer to draw to
  1880. \param where GSD_BOTH, GSD_FRONT, GSD_BACK
  1881. */
  1882. void GS_set_draw(int where)
  1883. {
  1884. Buffermode = where;
  1885. switch (where) {
  1886. case GSD_BOTH:
  1887. gsd_frontbuffer(1);
  1888. gsd_backbuffer(1);
  1889. break;
  1890. case GSD_FRONT:
  1891. gsd_frontbuffer(1);
  1892. gsd_backbuffer(0);
  1893. break;
  1894. case GSD_BACK:
  1895. default:
  1896. gsd_frontbuffer(0);
  1897. gsd_backbuffer(1);
  1898. break;
  1899. }
  1900. return;
  1901. }
  1902. /*
  1903. \brief Ready to draw
  1904. */
  1905. void GS_ready_draw(void)
  1906. {
  1907. G_debug(3, "GS_ready_draw");
  1908. gsd_set_view(&Gv, &Gd);
  1909. return;
  1910. }
  1911. /*!
  1912. \brief Draw done
  1913. */
  1914. void GS_done_draw(void)
  1915. {
  1916. G_debug(3, "GS_done_draw");
  1917. if (GSD_BACK == Buffermode) {
  1918. gsd_swapbuffers();
  1919. }
  1920. gsd_flush();
  1921. return;
  1922. }
  1923. /*!
  1924. \brief Set focus
  1925. \param realto real coordinates to
  1926. */
  1927. void GS_set_focus(float *realto)
  1928. {
  1929. G_debug(3, "GS_set_focus");
  1930. Gv.infocus = 1;
  1931. GS_v3eq(Gv.real_to, realto);
  1932. gsd_set_view(&Gv, &Gd);
  1933. return;
  1934. }
  1935. /*!
  1936. \brief Set real focus
  1937. \param realto real coordinates to
  1938. */
  1939. void GS_set_focus_real(float *realto)
  1940. {
  1941. G_get_set_window(&wind);
  1942. realto[X] = realto[X] - wind.west - (wind.ew_res/2.);
  1943. realto[Y] = realto[Y] - wind.south - (wind.ns_res/2.);
  1944. Gv.infocus = 1;
  1945. GS_v3eq(Gv.real_to, realto);
  1946. gsd_set_view(&Gv, &Gd);
  1947. return;
  1948. }
  1949. /*!
  1950. \brief Get focus
  1951. OK to call with NULL argument if just want to check state
  1952. \param realto real coordinates to
  1953. \return ?
  1954. */
  1955. int GS_get_focus(float *realto)
  1956. {
  1957. G_debug(3, "GS_get_focus");
  1958. if (Gv.infocus) {
  1959. if (realto) {
  1960. GS_v3eq(realto, Gv.real_to);
  1961. }
  1962. }
  1963. return (Gv.infocus);
  1964. }
  1965. /*!
  1966. \brief Set focus to map center
  1967. \param id surface id
  1968. */
  1969. void GS_set_focus_center_map(int id)
  1970. {
  1971. float center[3];
  1972. geosurf *gs;
  1973. G_debug(3, "GS_set_focus_center_map");
  1974. gs = gs_get_surf(id);
  1975. if (gs) {
  1976. center[X] = (gs->xmax - gs->xmin) / 2.;
  1977. center[Y] = (gs->ymax - gs->ymin) / 2.;
  1978. center[Z] = (gs->zmax_nz + gs->zmin_nz) / 2.;
  1979. /* not yet working
  1980. buff = gs_get_att_typbuff(gs, ATT_TOPO, 0);
  1981. offset = gs->rows*gs->cols/2 + gs->cols/2;
  1982. if (buff)
  1983. {
  1984. if (GET_MAPATT(buff, offset, tmp))
  1985. {
  1986. center[Z] = tmp;
  1987. }
  1988. }
  1989. */
  1990. GS_set_focus(center);
  1991. }
  1992. }
  1993. /*!
  1994. \brief Move position to
  1995. \param pt point model coordinates
  1996. */
  1997. void GS_moveto(float *pt)
  1998. {
  1999. float ft[3];
  2000. G_debug(3, "GS_moveto");
  2001. if (Gv.infocus) {
  2002. GS_v3eq(Gv.from_to[FROM], pt);
  2003. /*
  2004. GS_v3eq(Gv.from_to[TO], Gv.real_to);
  2005. */
  2006. GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]);
  2007. /* update inclination, look_dir if we're keeping these */
  2008. }
  2009. else {
  2010. GS_v3eq(ft, Gv.from_to[TO]);
  2011. GS_v3sub(ft, Gv.from_to[FROM]);
  2012. GS_v3eq(Gv.from_to[FROM], pt);
  2013. GS_v3eq(Gv.from_to[TO], pt);
  2014. GS_v3add(Gv.from_to[TO], ft);
  2015. }
  2016. return;
  2017. }
  2018. /*!
  2019. \brief Move position to (real)
  2020. \param pt point real coordinates
  2021. */
  2022. void GS_moveto_real(float *pt)
  2023. {
  2024. gsd_real2model(pt);
  2025. GS_moveto(pt);
  2026. return;
  2027. }
  2028. /*!
  2029. \brief Get z-extent for a single surface
  2030. \param id surface id
  2031. \param[out] min min z-value
  2032. \param[out] max max z-value
  2033. \param[out] mid middle z-value ?
  2034. \return -1 on error (invalid surface id)
  2035. \return ?
  2036. */
  2037. int GS_get_zextents(int id, float *min, float *max, float *mid)
  2038. {
  2039. geosurf *gs;
  2040. G_debug(3, "GS_get_zextents");
  2041. if (NULL == (gs = gs_get_surf(id))) {
  2042. return (-1);
  2043. }
  2044. return (gs_get_zextents(gs, min, max, mid));
  2045. }
  2046. /*!
  2047. \brief Get z-extent for all loaded surfaces
  2048. \param[out] min min z-value
  2049. \param[out] max max z-value
  2050. \param doexag ?
  2051. \return 1 on success
  2052. \return -1 on error
  2053. */
  2054. int GS_get_zrange(float *min, float *max, int doexag)
  2055. {
  2056. int ret_surf, ret_vol;
  2057. float surf_min, surf_max;
  2058. float vol_min, vol_max;
  2059. G_debug(3, "GS_get_zrange");
  2060. ret_surf = gs_get_zrange(&surf_min, &surf_max);
  2061. ret_vol = gvl_get_zrange(&vol_min, &vol_max);
  2062. if (ret_surf > 0 && ret_vol > 0) {
  2063. *min = (surf_min < vol_min) ? surf_min : vol_min;
  2064. *max = (surf_max < vol_max) ? surf_max : vol_max;
  2065. } else if (ret_surf > 0) {
  2066. *min = surf_min;
  2067. *max = surf_max;
  2068. } else if (ret_vol > 0) {
  2069. *min = vol_min;
  2070. *max = vol_max;
  2071. }
  2072. if (doexag) {
  2073. *min *= Gv.vert_exag;
  2074. *max *= Gv.vert_exag;
  2075. }
  2076. return ((ret_surf > 0 || ret_vol > 0) ? (1) :(-1));
  2077. }
  2078. /*!
  2079. \brief Get 'from' coordinates
  2080. \param[out] fr from model coordinates
  2081. */
  2082. void GS_get_from(float *fr)
  2083. {
  2084. G_debug(3, "GS_get_from");
  2085. GS_v3eq(fr, Gv.from_to[FROM]);
  2086. return;
  2087. }
  2088. /*!
  2089. \brief Get 'from' real coordinates
  2090. \param[out] fr 'from' real coordinates
  2091. */
  2092. void GS_get_from_real(float *fr)
  2093. {
  2094. GS_v3eq(fr, Gv.from_to[FROM]);
  2095. gsd_model2real(fr);
  2096. return;
  2097. }
  2098. /*!
  2099. \brief Get 'to' real coordinates
  2100. \param[out] to 'to' real coordinates
  2101. */
  2102. void GS_get_to_real(float *to)
  2103. {
  2104. float realto[3];
  2105. G_get_set_window(&wind);
  2106. GS_get_focus(realto);
  2107. to[X] = realto[X] + wind.west + (wind.ew_res/2.);
  2108. to[Y] = realto[Y] + wind.south + (wind.ns_res/2.);
  2109. to[Z] = realto[Z];
  2110. return;
  2111. }
  2112. /*!
  2113. \brief Get zoom setup
  2114. \param[out] a,b,c,d current viewport settings
  2115. \param[out] maxx,maxy max viewport size
  2116. */
  2117. void GS_zoom_setup(int *a, int *b, int *c, int *d, int *maxx, int *maxy)
  2118. {
  2119. GLint tmp[4];
  2120. GLint num[2];
  2121. gsd_getViewport(tmp, num);
  2122. *a = tmp[0];
  2123. *b = tmp[1];
  2124. *c = tmp[2];
  2125. *d = tmp[3];
  2126. *maxx = num[0];
  2127. *maxy = num[1];
  2128. return;
  2129. }
  2130. /*!
  2131. \brief Get 'to' model coordinates
  2132. \todo need set_to? - just use viewdir?
  2133. \param[out] to 'to' model coordinates
  2134. */
  2135. void GS_get_to(float *to)
  2136. {
  2137. G_debug(3, "GS_get_to");
  2138. GS_v3eq(to, Gv.from_to[TO]);
  2139. return;
  2140. }
  2141. /*!
  2142. \brief Get viewdir
  2143. \param[out] dir viewdir value
  2144. */
  2145. void GS_get_viewdir(float *dir)
  2146. {
  2147. GS_v3dir(Gv.from_to[FROM], Gv.from_to[TO], dir);
  2148. return;
  2149. }
  2150. /*!
  2151. \brief Set viewdir
  2152. Automatically turns off focus
  2153. \param dir viewdir value
  2154. */
  2155. void GS_set_viewdir(float *dir)
  2156. {
  2157. float tmp[3];
  2158. GS_v3eq(tmp, dir);
  2159. GS_v3norm(tmp);
  2160. GS_v3eq(Gv.from_to[TO], Gv.from_to[FROM]);
  2161. GS_v3add(Gv.from_to[TO], tmp);
  2162. GS_set_nofocus();
  2163. gsd_set_view(&Gv, &Gd);
  2164. return;
  2165. }
  2166. /*!
  2167. \brief Set field of view
  2168. \param fov fov value
  2169. */
  2170. void GS_set_fov(int fov)
  2171. {
  2172. Gv.fov = fov;
  2173. return;
  2174. }
  2175. /*!
  2176. \brief Get fied of view
  2177. \return field of view, in 10ths of degrees
  2178. */
  2179. int GS_get_fov(void)
  2180. {
  2181. return (Gv.fov);
  2182. }
  2183. /*!
  2184. \brief Get twist value
  2185. 10ths of degrees off twelve o'clock
  2186. */
  2187. int GS_get_twist(void)
  2188. {
  2189. return (Gv.twist);
  2190. }
  2191. /*!
  2192. \brief Set twist value
  2193. 10ths of degrees off twelve o'clock
  2194. \params t tenths of degrees clockwise from 12:00.
  2195. */
  2196. void GS_set_twist(int t)
  2197. {
  2198. Gv.twist = t;
  2199. return;
  2200. }
  2201. /*!
  2202. \brief Unset focus
  2203. */
  2204. void GS_set_nofocus(void)
  2205. {
  2206. G_debug(3, "GS_set_nofocus");
  2207. Gv.infocus = 0;
  2208. return;
  2209. }
  2210. /*!
  2211. \brief Set focus
  2212. Make sure that the center of view is set
  2213. */
  2214. void GS_set_infocus(void)
  2215. {
  2216. G_debug(3, "GS_set_infocus");
  2217. Gv.infocus = 1;
  2218. return;
  2219. }
  2220. /*!
  2221. \brief Set viewport
  2222. \param left,right,bottom,top viewport extent values
  2223. */
  2224. void GS_set_viewport(int left, int right, int bottom, int top)
  2225. {
  2226. G_debug(3, "GS_set_viewport");
  2227. gsd_viewport(left, right, bottom, top);
  2228. return;
  2229. }
  2230. /*!
  2231. \brief Send screen coords sx and sy, lib traces through surfaces; sets
  2232. new center to point of nearest intersection.
  2233. If no intersection, uses line of sight with length of current view
  2234. ray (eye to center) to set new center.
  2235. Reset center of view to screen coordinates sx, sy.
  2236. \param sx,sy screen coordinates
  2237. \return 1 on success
  2238. \return 0 on error (invalid surface id)
  2239. */
  2240. int GS_look_here(int sx, int sy)
  2241. {
  2242. float x, y, z, len, los[2][3];
  2243. Point3 realto, dir;
  2244. int id;
  2245. geosurf *gs;
  2246. if (GS_get_selected_point_on_surface(sx, sy, &id, &x, &y, &z)) {
  2247. gs = gs_get_surf(id);
  2248. if (gs) {
  2249. realto[X] = x - gs->ox + gs->x_trans;
  2250. realto[Y] = y - gs->oy + gs->y_trans;
  2251. realto[Z] = z + gs->z_trans;
  2252. GS_set_focus(realto);
  2253. return (1);
  2254. }
  2255. }
  2256. else {
  2257. if (gsd_get_los(los, (short) sx, (short) sy)) {
  2258. len = GS_distance(Gv.from_to[FROM], Gv.real_to);
  2259. GS_v3dir(los[FROM], los[TO], dir);
  2260. GS_v3mult(dir, len);
  2261. realto[X] = Gv.from_to[FROM][X] + dir[X];
  2262. realto[Y] = Gv.from_to[FROM][Y] + dir[Y];
  2263. realto[Z] = Gv.from_to[FROM][Z] + dir[Z];
  2264. GS_set_focus(realto);
  2265. return (1);
  2266. }
  2267. }
  2268. return (0);
  2269. }
  2270. /*!
  2271. \brief Get selected point of surface
  2272. Given screen coordinates sx and sy, find closest intersection of
  2273. view ray with surfaces and return coordinates of intersection in x, y,
  2274. z, and identifier of surface in id.
  2275. \param sx,sy screen coordinates
  2276. \param[out] id surface id
  2277. \param[out] x,y,z point on surface (model coordinates?)
  2278. \returns 0 if no intersections found
  2279. \return number of intersections
  2280. */
  2281. int GS_get_selected_point_on_surface(int sx, int sy, int *id, float *x,
  2282. float *y, float *z)
  2283. {
  2284. float los[2][3], find_dist[MAX_SURFS], closest;
  2285. Point3 point, tmp, finds[MAX_SURFS];
  2286. int surfs[MAX_SURFS], i, iclose, numhits = 0;
  2287. geosurf *gs;
  2288. /* returns surface-world coords */
  2289. gsd_get_los(los, (short) sx, (short) sy);
  2290. if (!gs_setlos_enterdata(los)) {
  2291. G_debug (3, "gs_setlos_enterdata(los): returns false");
  2292. return (0);
  2293. }
  2294. for (i = 0; i < Next_surf; i++) {
  2295. G_debug (3, "id=%d", i);
  2296. gs = gs_get_surf(Surf_ID[i]);
  2297. /* los_intersect expects surf-world coords (xy transl, no scaling) */
  2298. #if NVIZ_HACK
  2299. if (gs_los_intersect1(Surf_ID[i], los, point)) {
  2300. #else
  2301. if (gs_los_intersect(Surf_ID[i], los, point)) {
  2302. #endif
  2303. if (!gs_point_is_masked(gs, point)) {
  2304. GS_v3eq(tmp, point);
  2305. tmp[X] += gs->x_trans;
  2306. tmp[Y] += gs->y_trans;
  2307. tmp[Z] += gs->z_trans;
  2308. find_dist[numhits] = GS_distance(los[FROM], tmp);
  2309. gsd_surf2real(gs, point);
  2310. GS_v3eq(finds[numhits], point);
  2311. surfs[numhits] = Surf_ID[i];
  2312. numhits++;
  2313. }
  2314. }
  2315. }
  2316. for (i = iclose = 0; i < numhits; i++) {
  2317. closest = find_dist[iclose];
  2318. if (find_dist[i] < closest) {
  2319. iclose = i;
  2320. }
  2321. }
  2322. if (numhits) {
  2323. *x = finds[iclose][X];
  2324. *y = finds[iclose][Y];
  2325. *z = finds[iclose][Z];
  2326. *id = surfs[iclose];
  2327. }
  2328. G_debug(3, "NumHits %d, next %d", numhits, Next_surf);
  2329. return (numhits);
  2330. }
  2331. /*!
  2332. \brief Set cplace rotation
  2333. \param num cplace id
  2334. \param dx,dy,dz rotation values
  2335. */
  2336. void GS_set_cplane_rot(int num, float dx, float dy, float dz)
  2337. {
  2338. gsd_cplane_setrot(num, dx, dy, dz);
  2339. return;
  2340. }
  2341. /*!
  2342. \brief Set cplace trans
  2343. \param num cplace id
  2344. \param dx,dy,dz rotation values
  2345. */
  2346. void GS_set_cplane_trans(int num, float dx, float dy, float dz)
  2347. {
  2348. gsd_cplane_settrans(num, dx, dy, dz);
  2349. return;
  2350. }
  2351. /*!
  2352. \brief Draw cplace
  2353. \param num cplace id
  2354. */
  2355. void GS_draw_cplane(int num)
  2356. {
  2357. geosurf *gsurfs[MAX_SURFS];
  2358. int nsurfs;
  2359. nsurfs = gs_num_surfaces();
  2360. if (2 == nsurfs) {
  2361. /* testing */
  2362. gs_getall_surfaces(gsurfs);
  2363. gsd_draw_cplane_fence(gsurfs[0], gsurfs[1], num);
  2364. }
  2365. else {
  2366. gsd_draw_cplane(num);
  2367. }
  2368. return;
  2369. }
  2370. /*!
  2371. \brief Draw cplace fence ?
  2372. \param hs1,hs2
  2373. \param num cplane id
  2374. \return 0 on error
  2375. \return 1 on success
  2376. */
  2377. int GS_draw_cplane_fence(int hs1, int hs2, int num)
  2378. {
  2379. geosurf *gs1, *gs2;
  2380. if (NULL == (gs1 = gs_get_surf(hs1))) {
  2381. return (0);
  2382. }
  2383. if (NULL == (gs2 = gs_get_surf(hs2))) {
  2384. return (0);
  2385. }
  2386. gsd_draw_cplane_fence(gs1, gs2, num);
  2387. return (1);
  2388. }
  2389. /*!
  2390. \brief Draw all cplace fences ?
  2391. */
  2392. void GS_alldraw_cplane_fences(void)
  2393. {
  2394. int onstate[MAX_CPLANES], i;
  2395. gsd_get_cplanes_state(onstate);
  2396. for (i = 0; i < MAX_CPLANES; i++) {
  2397. if (onstate[i]) {
  2398. GS_draw_cplane_fence(Surf_ID[0], Surf_ID[1], i);
  2399. }
  2400. }
  2401. return;
  2402. }
  2403. /*!
  2404. \brief Set cplace
  2405. \param num cplane id
  2406. */
  2407. void GS_set_cplane(int num)
  2408. {
  2409. gsd_cplane_on(num);
  2410. return;
  2411. }
  2412. /*!
  2413. \brief Unset cplace
  2414. \param num cplane id
  2415. */
  2416. void GS_unset_cplane(int num)
  2417. {
  2418. gsd_cplane_off(num);
  2419. return;
  2420. }
  2421. /*!
  2422. \brief Get scale
  2423. \param sx,sy,sz x/y/z scale values
  2424. \param doexag ?
  2425. */
  2426. void GS_get_scale(float *sx, float *sy, float *sz, int doexag)
  2427. {
  2428. float zexag;
  2429. zexag = doexag ? Gv.vert_exag : 1.;
  2430. *sx = *sy = Gv.scale;
  2431. *sz = Gv.scale * zexag;
  2432. return;
  2433. }
  2434. /*!
  2435. \brief Set fence color
  2436. \param mode mode id
  2437. */
  2438. void GS_set_fencecolor(int mode)
  2439. {
  2440. gsd_setfc(mode);
  2441. return;
  2442. }
  2443. /*!
  2444. \brief Get fence color
  2445. \return color value
  2446. */
  2447. int GS_get_fencecolor(void)
  2448. {
  2449. return gsd_getfc();
  2450. }
  2451. /*!
  2452. \brief Measure distance "as the ball rolls" between two points on surface
  2453. \param hs
  2454. \param x1,y1,x2,y2 distance line nodes
  2455. \param dist ?
  2456. \param use_exag use exag ?
  2457. \return 0 on error or if one or more points is not in region,
  2458. \return distance following terrain
  2459. */
  2460. int GS_get_distance_alongsurf(int hs, float x1, float y1, float x2, float y2,
  2461. float *dist, int use_exag)
  2462. {
  2463. geosurf *gs;
  2464. float p1[2], p2[2];
  2465. if (NULL == (gs = gs_get_surf(hs))) {
  2466. return (0);
  2467. }
  2468. p1[X] = x1;
  2469. p1[Y] = y1;
  2470. p2[X] = x2;
  2471. p2[Y] = y2;
  2472. gsd_real2surf(gs, p1);
  2473. gsd_real2surf(gs, p2);
  2474. return (gs_distance_onsurf(gs, p1, p2, dist, use_exag));
  2475. }
  2476. /*!
  2477. \brief Save 3d view
  2478. \param vname view file name
  2479. \param surfid surface id
  2480. \return ?
  2481. */
  2482. int GS_save_3dview(char *vname, int surfid)
  2483. {
  2484. return (Gs_save_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid)));
  2485. }
  2486. /*!
  2487. \brief Load 3d view
  2488. \param vname view file name
  2489. \param surfid surface id
  2490. \return ?
  2491. */
  2492. int GS_load_3dview(char *vname, int surfid)
  2493. {
  2494. return (Gs_load_3dview(vname, &Gv, &Gd, &wind, gs_get_surf(surfid)));
  2495. /* what to do about lights - I guess, delete all &
  2496. create any that exist in 3dview file */
  2497. }
  2498. /************************************************************************
  2499. * Following routines use Graphics Library
  2500. ************************************************************************/
  2501. /*!
  2502. \brief Init view
  2503. \todo allow to set center?
  2504. */
  2505. void GS_init_view(void)
  2506. {
  2507. static int first = 1;
  2508. G_debug(3, "GS_init_view");
  2509. if (first) {
  2510. first = 0;
  2511. glMatrixMode(GL_MODELVIEW);
  2512. /* OGLXXX doublebuffer: use GLX_DOUBLEBUFFER in attriblist */
  2513. /* glxChooseVisual(*dpy, screen, *attriblist); */
  2514. /* OGLXXX
  2515. * ZMIN not needed -- always 0.
  2516. * ZMAX not needed -- always 1.
  2517. * getgdesc other posiblilties:
  2518. * glxGetConfig();
  2519. * glxGetCurrentContext();
  2520. * glxGetCurrentDrawable();
  2521. * GLint gdtmp;
  2522. * getgdesc other posiblilties:
  2523. * glxGetConfig();
  2524. * glxGetCurrentContext();
  2525. * glxGetCurrentDrawable();
  2526. * GLint gdtmp;
  2527. * glDepthRange params must be scaled to [0, 1]
  2528. */
  2529. glDepthRange(0.0, 1.0);
  2530. glEnable(GL_DEPTH_TEST);
  2531. glDepthFunc(GL_LEQUAL);
  2532. /* } */
  2533. /* replace these with something meaningful */
  2534. Gv.fov = 450;
  2535. Gv.twist = 0;
  2536. Gv.from_to[FROM][X] = Gv.from_to[FROM][Y] =
  2537. Gv.from_to[FROM][Z] = GS_UNIT_SIZE / 2.;
  2538. Gv.from_to[TO][X] = GS_UNIT_SIZE / 2.;
  2539. Gv.from_to[TO][Y] = GS_UNIT_SIZE / 2.;
  2540. Gv.from_to[TO][Z] = 0.;
  2541. Gv.from_to[TO][W] = Gv.from_to[FROM][W] = 1.;
  2542. Gv.real_to[W] = 1.;
  2543. Gv.vert_exag = 1.;
  2544. GS_v3eq(Gv.real_to, Gv.from_to[TO]);
  2545. GS_v3normalize(Gv.from_to[FROM], Gv.from_to[TO]);
  2546. /*
  2547. Gd.nearclip = 50;
  2548. Gd.farclip = 10000.;
  2549. */
  2550. Gd.nearclip = 10.;
  2551. Gd.farclip = 10000.;
  2552. Gd.aspect = (float) GS_get_aspect();
  2553. GS_set_focus(Gv.real_to);
  2554. }
  2555. return;
  2556. }
  2557. /*!
  2558. \brief Clear view
  2559. \param col color value
  2560. */
  2561. void GS_clear(int col)
  2562. {
  2563. G_debug(3, "GS_clear");
  2564. col = col | 0xFF000000;
  2565. /* OGLXXX
  2566. * change glClearDepth parameter to be in [0, 1]
  2567. * ZMAX not needed -- always 1.
  2568. * getgdesc other posiblilties:
  2569. * glxGetConfig();
  2570. * glxGetCurrentContext();
  2571. * glxGetCurrentDrawable();
  2572. * GLint gdtmp;
  2573. */
  2574. glClearDepth(1.0);
  2575. glClearColor(((float) ((col) & 0xff)) / 255.,
  2576. (float) ((col) >> 8 & 0xff) / 255.,
  2577. (float) ((col) >> 16 & 0xff) / 255.,
  2578. (float) ((col) >> 24 & 0xff) / 255.);
  2579. glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  2580. Gd.bgcol = col;
  2581. Modelshowing = 0;
  2582. gsd_flush();
  2583. return;
  2584. }
  2585. /*!
  2586. \brief Get aspect value
  2587. */
  2588. double GS_get_aspect(void)
  2589. {
  2590. int left, right, bottom, top;
  2591. GLint tmp[4];
  2592. G_debug(3, "GS_get_aspect");
  2593. /* OGLXXX
  2594. * get GL_VIEWPORT:
  2595. * You can probably do better than this.
  2596. */
  2597. glGetIntegerv(GL_VIEWPORT, tmp);
  2598. left = tmp[0];
  2599. right = tmp[0] + tmp[2] - 1;
  2600. bottom = tmp[1];
  2601. top = tmp[1] + tmp[3] - 1;
  2602. return ((double) (right - left) / (top - bottom));
  2603. }
  2604. /*!
  2605. \brief Check for transparency
  2606. Disabled.
  2607. \return 1
  2608. */
  2609. int GS_has_transparency(void)
  2610. {
  2611. /* OGLXXX
  2612. * getgdesc other posiblilties:
  2613. * glxGetConfig();
  2614. * glxGetCurrentContext();
  2615. * glxGetCurrentDrawable();
  2616. * GLint gdtmp;
  2617. * blending is ALWAYS supported.
  2618. * This function returns whether it is enabled.
  2619. * return((glGetIntegerv(GL_BLEND, &gdtmp), gdtmp));
  2620. */
  2621. return (1);
  2622. }