gsd_prim.c 20 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195
  1. /*!
  2. \file lib/ogsf/gsd_prim.c
  3. \brief OGSF library - primitive drawing functions (lower level functions)
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Bill Brown USACERL (January 1993)
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <grass/config.h>
  16. #if defined(OPENGL_X11)
  17. #include <GL/gl.h>
  18. #include <GL/glu.h>
  19. #include <GL/glx.h>
  20. #elif defined(OPENGL_AQUA)
  21. #include <OpenGL/gl.h>
  22. #include <OpenGL/glu.h>
  23. #include <AGL/agl.h>
  24. #elif defined(OPENGL_WINDOWS)
  25. #include <GL/gl.h>
  26. #include <GL/glu.h>
  27. #include <wingdi.h>
  28. #endif
  29. #include <grass/gis.h>
  30. #include <grass/ogsf.h>
  31. #include <grass/glocale.h>
  32. #define USE_GL_NORMALIZE
  33. #define RED_MASK 0x000000FF
  34. #define GRN_MASK 0x0000FF00
  35. #define BLU_MASK 0x00FF0000
  36. #define ALP_MASK 0xFF000000
  37. #define INT_TO_RED(i, r) (r = (i & RED_MASK))
  38. #define INT_TO_GRN(i, g) (g = (i & GRN_MASK) >> 8)
  39. #define INT_TO_BLU(i, b) (b = (i & BLU_MASK) >> 16)
  40. #define INT_TO_ALP(i, a) (a = (i & ALP_MASK) >> 24)
  41. #define MAX_OBJS 64
  42. /* ^ TMP - move to gstypes */
  43. /* define border width (pixels) for viewport check */
  44. #define border 15
  45. static GLuint ObjList[MAX_OBJS];
  46. static int numobjs = 0;
  47. static int Shade;
  48. static float ogl_light_amb[MAX_LIGHTS][4];
  49. static float ogl_light_diff[MAX_LIGHTS][4];
  50. static float ogl_light_spec[MAX_LIGHTS][4];
  51. static float ogl_light_pos[MAX_LIGHTS][4];
  52. static float ogl_mat_amb[4];
  53. static float ogl_mat_diff[4];
  54. static float ogl_mat_spec[4];
  55. static float ogl_mat_emis[4];
  56. static float ogl_mat_shin;
  57. /*!
  58. \brief Mostly for flushing drawing commands accross a network
  59. glFlush doesn't block, so if blocking is desired use glFinish.
  60. */
  61. void gsd_flush(void)
  62. {
  63. glFlush();
  64. return;
  65. }
  66. /*!
  67. \brief Set color mode
  68. Call glColorMaterial before enabling the GL_COLOR_MATERIAL
  69. \param cm color mode value
  70. */
  71. void gsd_colormode(int cm)
  72. {
  73. switch (cm) {
  74. case CM_COLOR:
  75. glDisable(GL_COLOR_MATERIAL);
  76. glDisable(GL_LIGHTING);
  77. break;
  78. case CM_EMISSION:
  79. glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
  80. glEnable(GL_COLOR_MATERIAL);
  81. glEnable(GL_LIGHTING);
  82. break;
  83. case CM_DIFFUSE:
  84. glColorMaterial(GL_FRONT, GL_DIFFUSE);
  85. glEnable(GL_COLOR_MATERIAL);
  86. glEnable(GL_LIGHTING);
  87. break;
  88. case CM_AD:
  89. glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
  90. glEnable(GL_COLOR_MATERIAL);
  91. glEnable(GL_LIGHTING);
  92. break;
  93. case CM_NULL:
  94. /* OGLXXX
  95. * lmcolor: if LMC_NULL, use:
  96. * glDisable(GL_COLOR_MATERIAL);
  97. * LMC_NULL: use glDisable(GL_COLOR_MATERIAL);
  98. */
  99. glDisable(GL_COLOR_MATERIAL);
  100. glEnable(GL_LIGHTING);
  101. break;
  102. default:
  103. glDisable(GL_COLOR_MATERIAL);
  104. break;
  105. }
  106. return;
  107. }
  108. /*!
  109. \brief Print color mode to stderr
  110. */
  111. void show_colormode(void)
  112. {
  113. GLint mat;
  114. glGetIntegerv(GL_COLOR_MATERIAL_PARAMETER, &mat);
  115. G_message(_("Color Material: %d"), mat);
  116. return;
  117. }
  118. /*!
  119. \brief ADD
  120. \param x,y
  121. \param rad
  122. */
  123. void gsd_circ(float x, float y, float rad)
  124. {
  125. GLUquadricObj *qobj = gluNewQuadric();
  126. gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
  127. glPushMatrix();
  128. glTranslatef(x, y, 0.);
  129. gluDisk(qobj, 0., rad, 32, 1);
  130. glPopMatrix();
  131. gluDeleteQuadric(qobj);
  132. return;
  133. }
  134. /*!
  135. \brief ADD
  136. \param x,y,z
  137. \param rad
  138. */
  139. void gsd_disc(float x, float y, float z, float rad)
  140. {
  141. GLUquadricObj *qobj = gluNewQuadric();
  142. gluQuadricDrawStyle(qobj, GLU_FILL);
  143. glPushMatrix();
  144. glTranslatef(x, y, z);
  145. gluDisk(qobj, 0., rad, 32, 1);
  146. glPopMatrix();
  147. gluDeleteQuadric(qobj);
  148. return;
  149. }
  150. /*!
  151. \brief ADD
  152. \param center center-point
  153. \param siz size value
  154. */
  155. void gsd_sphere(float *center, float siz)
  156. {
  157. static int first = 1;
  158. static GLUquadricObj *QOsphere;
  159. if (first) {
  160. QOsphere = gluNewQuadric();
  161. if (QOsphere) {
  162. gluQuadricNormals(QOsphere, GLU_SMOOTH); /* default */
  163. gluQuadricTexture(QOsphere, GL_FALSE); /* default */
  164. gluQuadricOrientation(QOsphere, GLU_OUTSIDE); /* default */
  165. gluQuadricDrawStyle(QOsphere, GLU_FILL);
  166. }
  167. first = 0;
  168. }
  169. glPushMatrix();
  170. glTranslatef(center[0], center[1], center[2]);
  171. gluSphere(QOsphere, (double)siz, 24, 24);
  172. glPopMatrix();
  173. return;
  174. }
  175. /*!
  176. \brief Write out z-mask
  177. Enable or disable writing into the depth buffer
  178. \param n Specifies whether the depth buffer is enabled for
  179. writing
  180. */
  181. void gsd_zwritemask(unsigned long n)
  182. {
  183. /* OGLXXX glDepthMask is boolean only */
  184. glDepthMask((GLboolean) (n));
  185. return;
  186. }
  187. /*!
  188. \brief ADD
  189. \param n
  190. */
  191. void gsd_backface(int n)
  192. {
  193. glCullFace(GL_BACK);
  194. (n) ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE);
  195. return;
  196. }
  197. /*!
  198. \brief Set width of rasterized lines
  199. \param n line width
  200. */
  201. void gsd_linewidth(short n)
  202. {
  203. glLineWidth((GLfloat) (n));
  204. return;
  205. }
  206. /*!
  207. \brief ADD
  208. */
  209. void gsd_bgnqstrip(void)
  210. {
  211. glBegin(GL_QUAD_STRIP);
  212. return;
  213. }
  214. /*!
  215. \brief ADD
  216. */
  217. void gsd_endqstrip(void)
  218. {
  219. glEnd();
  220. return;
  221. }
  222. /*!
  223. \brief ADD
  224. */
  225. void gsd_bgntmesh(void)
  226. {
  227. glBegin(GL_TRIANGLE_STRIP);
  228. return;
  229. }
  230. /*!
  231. \brief ADD
  232. */
  233. void gsd_endtmesh(void)
  234. {
  235. glEnd();
  236. return;
  237. }
  238. /*!
  239. \brief ADD
  240. */
  241. void gsd_bgntstrip(void)
  242. {
  243. glBegin(GL_TRIANGLE_STRIP);
  244. return;
  245. }
  246. /*!
  247. \brief ADD
  248. */
  249. void gsd_endtstrip(void)
  250. {
  251. glEnd();
  252. return;
  253. }
  254. /*!
  255. \brief ADD
  256. */
  257. void gsd_bgntfan(void)
  258. {
  259. glBegin(GL_TRIANGLE_FAN);
  260. return;
  261. }
  262. /*!
  263. \brief ADD
  264. */
  265. void gsd_endtfan(void)
  266. {
  267. glEnd();
  268. return;
  269. }
  270. /*!
  271. \brief ADD
  272. */
  273. void gsd_swaptmesh(void)
  274. {
  275. /* OGLXXX
  276. * swaptmesh not supported, maybe glBegin(GL_TRIANGLE_FAN)
  277. * swaptmesh()
  278. */
  279. /*DELETED*/;
  280. return;
  281. }
  282. /*!
  283. \brief Delimit the vertices of a primitive or a group of like primitives
  284. */
  285. void gsd_bgnpolygon(void)
  286. {
  287. /* OGLXXX
  288. * special cases for polygons:
  289. * independant quads: use GL_QUADS
  290. * independent triangles: use GL_TRIANGLES
  291. */
  292. glBegin(GL_POLYGON);
  293. return;
  294. }
  295. /*!
  296. \brief Delimit the vertices of a primitive or a group of like primitives
  297. */
  298. void gsd_endpolygon(void)
  299. {
  300. glEnd();
  301. return;
  302. }
  303. /*!
  304. \brief Begin line
  305. */
  306. void gsd_bgnline(void)
  307. {
  308. /* OGLXXX for multiple, independent line segments: use GL_LINES */
  309. glBegin(GL_LINE_STRIP);
  310. return;
  311. }
  312. /*!
  313. \brief End line
  314. */
  315. void gsd_endline(void)
  316. {
  317. glEnd();
  318. return;
  319. }
  320. /*!
  321. \brief Set shaded model
  322. \param shade non-zero for GL_SMOOTH otherwise GL_FLAT
  323. */
  324. void gsd_shademodel(int shade)
  325. {
  326. Shade = shade;
  327. if (shade) {
  328. glShadeModel(GL_SMOOTH);
  329. }
  330. else {
  331. glShadeModel(GL_FLAT);
  332. }
  333. return;
  334. }
  335. /*!
  336. \brief Get shaded model
  337. \return shade
  338. */
  339. int gsd_getshademodel(void)
  340. {
  341. return (Shade);
  342. }
  343. /*!
  344. \brief Draw to the front and back buffers
  345. */
  346. void gsd_bothbuffers(void)
  347. {
  348. /* OGLXXX bothbuffer: other possibilities include GL_FRONT, GL_BACK */
  349. glDrawBuffer(GL_FRONT_AND_BACK);
  350. return;
  351. }
  352. /*!
  353. \brief Draw to the front buffer
  354. */
  355. void gsd_frontbuffer(void)
  356. {
  357. /* OGLXXX frontbuffer: other possibilities include GL_FRONT_AND_BACK */
  358. glDrawBuffer(GL_FRONT);
  359. return;
  360. }
  361. /*!
  362. \brief Draw to the back buffer
  363. */
  364. void gsd_backbuffer(void)
  365. {
  366. /* OGLXXX backbuffer: other possibilities include GL_FRONT_AND_BACK */
  367. glDrawBuffer(GL_BACK);
  368. return;
  369. }
  370. /*!
  371. \brief Swap buffers
  372. */
  373. void gsd_swapbuffers(void)
  374. {
  375. /* OGLXXX swapbuffers: copy the back buffer to the front;
  376. * the back buffer becomes undefined afterward */
  377. #if defined(OPENGL_X11)
  378. glXSwapBuffers(glXGetCurrentDisplay(), glXGetCurrentDrawable());
  379. #elif defined(OPENGL_AQUA)
  380. aglSwapBuffers(aglGetCurrentContext());
  381. #elif defined(OPENGL_WINDOWS)
  382. /* TODO: Doesn't compile? Undefined reference to __imp_SwapBuffers
  383. SwapBuffers(wglGetCurrentDC());
  384. */
  385. #endif
  386. return;
  387. }
  388. /*!
  389. \brief Pop the current matrix stack
  390. */
  391. void gsd_popmatrix(void)
  392. {
  393. glPopMatrix();
  394. return;
  395. }
  396. /*!
  397. \brief Push the current matrix stack
  398. */
  399. void gsd_pushmatrix(void)
  400. {
  401. glPushMatrix();
  402. return;
  403. }
  404. /*!
  405. \brief Multiply the current matrix by a general scaling matrix
  406. \param xs x scale value
  407. \param ys y scale value
  408. \param zs z scale value
  409. */
  410. void gsd_scale(float xs, float ys, float zs)
  411. {
  412. glScalef(xs, ys, zs);
  413. return;
  414. }
  415. /*!
  416. \brief Multiply the current matrix by a translation matrix
  417. \param dx x translation value
  418. \param dy y translation value
  419. \param dz z translation value
  420. */
  421. void gsd_translate(float dx, float dy, float dz)
  422. {
  423. glTranslatef(dx, dy, dz);
  424. return;
  425. }
  426. /*!
  427. \brief Get viewport
  428. \param[out] window
  429. \param viewport
  430. \param modelMatrix model matrix
  431. \param projMatrix projection matrix
  432. */
  433. void gsd_getwindow(int *window, int *viewport, double *modelMatrix,
  434. double *projMatrix)
  435. {
  436. gsd_pushmatrix();
  437. gsd_do_scale(1);
  438. glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
  439. glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
  440. glGetIntegerv(GL_VIEWPORT, viewport);
  441. gsd_popmatrix();
  442. window[0] = viewport[1] + viewport[3] + border;
  443. window[1] = viewport[1] - border;
  444. window[2] = viewport[0] - border;
  445. window[3] = viewport[0] + viewport[2] + border;
  446. return;
  447. }
  448. /*!
  449. \brief ADD
  450. \param pt
  451. \param widnow
  452. \param viewport
  453. \param doubleMatrix
  454. \param projMatrix
  455. \return 0
  456. \return 1
  457. */
  458. int gsd_checkpoint(float pt[4],
  459. int window[4],
  460. int viewport[4],
  461. double modelMatrix[16], double projMatrix[16])
  462. {
  463. GLdouble fx, fy, fz;
  464. gluProject((GLdouble) pt[X], (GLdouble) pt[Y], (GLdouble) pt[Z],
  465. modelMatrix, projMatrix, viewport, &fx, &fy, &fz);
  466. if (fx < window[2] || fx > window[3]
  467. || fy < window[1] || fy > window[0])
  468. return 1;
  469. else
  470. return 0;
  471. }
  472. /*!
  473. \brief ADD
  474. \param angle
  475. \param axis
  476. */
  477. void gsd_rot(float angle, char axis)
  478. {
  479. GLfloat x;
  480. GLfloat y;
  481. GLfloat z;
  482. switch (axis) {
  483. case 'x':
  484. case 'X':
  485. x = 1.0;
  486. y = 0.0;
  487. z = 0.0;
  488. break;
  489. case 'y':
  490. case 'Y':
  491. x = 0.0;
  492. y = 1.0;
  493. z = 0.0;
  494. break;
  495. case 'z':
  496. case 'Z':
  497. x = 0.0;
  498. y = 0.0;
  499. z = 1.0;
  500. break;
  501. default:
  502. G_warning(_("gsd_rot(): %c is an invalid axis "
  503. "specification. Rotation ignored. "
  504. "Please advise GRASS developers of this error"), axis);
  505. return;
  506. }
  507. glRotatef((GLfloat) angle, x, y, z);
  508. return;
  509. }
  510. /*!
  511. \brief Set the current normal vector & specify vertex
  512. \param norm normal vector
  513. \param col color value
  514. \param pt point (model coordinates)
  515. */
  516. void gsd_litvert_func(float *norm, unsigned long col, float *pt)
  517. {
  518. glNormal3fv(norm);
  519. gsd_color_func(col);
  520. glVertex3fv(pt);
  521. return;
  522. }
  523. /*!
  524. \brief ADD
  525. \param norm
  526. \param col
  527. \param pt
  528. */
  529. void gsd_litvert_func2(float *norm, unsigned long col, float *pt)
  530. {
  531. glNormal3fv(norm);
  532. glVertex3fv(pt);
  533. return;
  534. }
  535. /*!
  536. \brief ADD
  537. \param pt
  538. */
  539. void gsd_vert_func(float *pt)
  540. {
  541. glVertex3fv(pt);
  542. return;
  543. }
  544. /*!
  545. \brief Set current color
  546. \param col color value
  547. */
  548. void gsd_color_func(unsigned int col)
  549. {
  550. GLbyte r, g, b, a;
  551. /* OGLXXX
  552. * cpack: if argument is not a variable
  553. * might need to be:
  554. * glColor4b(($1)&0xff, ($1)>>8&0xff, ($1)>>16&0xff, ($1)>>24&0xff)
  555. */
  556. INT_TO_RED(col, r);
  557. INT_TO_GRN(col, g);
  558. INT_TO_BLU(col, b);
  559. INT_TO_ALP(col, a);
  560. glColor4ub(r, g, b, a);
  561. return;
  562. }
  563. /*!
  564. \brief Initialize model light
  565. */
  566. void gsd_init_lightmodel(void)
  567. {
  568. glEnable(GL_LIGHTING);
  569. /* normal vector renormalization */
  570. #ifdef USE_GL_NORMALIZE
  571. {
  572. glEnable(GL_NORMALIZE);
  573. }
  574. #endif
  575. /* OGLXXX
  576. * Ambient:
  577. * If this is a light model lmdef, then use
  578. * glLightModelf and GL_LIGHT_MODEL_AMBIENT.
  579. * Include ALPHA parameter with ambient
  580. */
  581. /* Default is front face lighting, infinite viewer
  582. */
  583. ogl_mat_amb[0] = 0.1;
  584. ogl_mat_amb[1] = 0.1;
  585. ogl_mat_amb[2] = 0.1;
  586. ogl_mat_amb[3] = 1.0;
  587. ogl_mat_diff[0] = 0.8;
  588. ogl_mat_diff[1] = 0.8;
  589. ogl_mat_diff[2] = 0.8;
  590. ogl_mat_diff[3] = 0.8;
  591. ogl_mat_spec[0] = 0.8;
  592. ogl_mat_spec[1] = 0.8;
  593. ogl_mat_spec[2] = 0.8;
  594. ogl_mat_spec[3] = 0.8;
  595. ogl_mat_emis[0] = 0.0;
  596. ogl_mat_emis[1] = 0.0;
  597. ogl_mat_emis[2] = 0.0;
  598. ogl_mat_emis[3] = 0.0;
  599. ogl_mat_shin = 25.0;
  600. /* OGLXXX
  601. * attenuation: see glLightf man page: (ignored for infinite lights)
  602. * Add GL_LINEAR_ATTENUATION.
  603. sgi_lmodel[0] = GL_CONSTANT_ATTENUATION;
  604. sgi_lmodel[1] = 1.0;
  605. sgi_lmodel[2] = 0.0;
  606. sgi_lmodel[3] = ;
  607. */
  608. /* OGLXXX
  609. * lmdef other possibilities include:
  610. * glLightf(light, pname, *params);
  611. * glLightModelf(pname, param);
  612. * Check list numbering.
  613. * Translate params as needed.
  614. */
  615. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ogl_mat_amb);
  616. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, ogl_mat_diff);
  617. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ogl_mat_spec);
  618. glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, ogl_mat_emis);
  619. glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, ogl_mat_shin);
  620. /* OGLXXX lmbind: check object numbering. */
  621. /* OGLXXX
  622. * lmbind: check object numbering.
  623. * Use GL_FRONT in call to glMaterialf.
  624. * Use GL_FRONT in call to glMaterialf.
  625. if(1) {glCallList(1); glEnable(LMODEL);} else glDisable(LMODEL);
  626. if(1) {glCallList(1); glEnable(GL_FRONT);} else glDisable(GL_FRONT);
  627. */
  628. return;
  629. }
  630. /*!
  631. \brief Set material
  632. \param set_shin,set_emis flags
  633. \param sh,em should be 0. - 1.
  634. \param emcolor packed colors to use for emission
  635. */
  636. void gsd_set_material(int set_shin, int set_emis, float sh, float em,
  637. int emcolor)
  638. {
  639. if (set_shin) {
  640. ogl_mat_spec[0] = sh;
  641. ogl_mat_spec[1] = sh;
  642. ogl_mat_spec[2] = sh;
  643. ogl_mat_spec[3] = sh;
  644. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ogl_mat_spec);
  645. ogl_mat_shin = 60. + (int)(sh * 68.);
  646. glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, ogl_mat_shin);
  647. }
  648. if (set_emis) {
  649. ogl_mat_emis[0] = (em * (emcolor & 0x0000FF)) / 255.;
  650. ogl_mat_emis[1] = (em * ((emcolor & 0x00FF00) >> 8)) / 255.;
  651. ogl_mat_emis[2] = (em * ((emcolor & 0xFF0000) >> 16)) / 255.;
  652. glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, ogl_mat_emis);
  653. }
  654. return;
  655. }
  656. /*!
  657. \brief Define light
  658. \param num light id (starts with 1)
  659. \param vals position(x,y,z,w), color, ambientm, emission
  660. */
  661. void gsd_deflight(int num, struct lightdefs *vals)
  662. {
  663. if (num > 0 && num <= MAX_LIGHTS) {
  664. ogl_light_pos[num - 1][0] = vals->position[X];
  665. ogl_light_pos[num - 1][1] = vals->position[Y];
  666. ogl_light_pos[num - 1][2] = vals->position[Z];
  667. ogl_light_pos[num - 1][3] = vals->position[W];
  668. glLightfv(GL_LIGHT0 + num, GL_POSITION, ogl_light_pos[num - 1]);
  669. ogl_light_diff[num - 1][0] = vals->color[0];
  670. ogl_light_diff[num - 1][1] = vals->color[1];
  671. ogl_light_diff[num - 1][2] = vals->color[2];
  672. ogl_light_diff[num - 1][3] = .3;
  673. glLightfv(GL_LIGHT0 + num, GL_DIFFUSE, ogl_light_diff[num - 1]);
  674. ogl_light_amb[num - 1][0] = vals->ambient[0];
  675. ogl_light_amb[num - 1][1] = vals->ambient[1];
  676. ogl_light_amb[num - 1][2] = vals->ambient[2];
  677. ogl_light_amb[num - 1][3] = .3;
  678. glLightfv(GL_LIGHT0 + num, GL_AMBIENT, ogl_light_amb[num - 1]);
  679. ogl_light_spec[num - 1][0] = vals->color[0];
  680. ogl_light_spec[num - 1][1] = vals->color[1];
  681. ogl_light_spec[num - 1][2] = vals->color[2];
  682. ogl_light_spec[num - 1][3] = .3;
  683. glLightfv(GL_LIGHT0 + num, GL_SPECULAR, ogl_light_spec[num - 1]);
  684. }
  685. return;
  686. }
  687. /*!
  688. \brief Switch light on/off
  689. \param num
  690. \param on 1 for 'on', 0 turns them off
  691. */
  692. void gsd_switchlight(int num, int on)
  693. {
  694. short defin;
  695. defin = on ? num : 0;
  696. if (defin) {
  697. glEnable(GL_LIGHT0 + num);
  698. }
  699. else {
  700. glDisable(GL_LIGHT0 + num);
  701. }
  702. return;
  703. }
  704. /*!
  705. \brief Get image of current GL screen
  706. \param pixbuf data buffer
  707. \param[out] xsize,ysize picture dimension
  708. \return 0 on failure
  709. \return 1 on success
  710. */
  711. int gsd_getimage(unsigned char **pixbuf, unsigned int *xsize,
  712. unsigned int *ysize)
  713. {
  714. GLuint l, r, b, t;
  715. /* OGLXXX
  716. * get GL_VIEWPORT:
  717. * You can probably do better than this.
  718. */
  719. GLint tmp[4];
  720. glGetIntegerv(GL_VIEWPORT, tmp);
  721. l = tmp[0];
  722. r = tmp[0] + tmp[2] - 1;
  723. b = tmp[1];
  724. t = tmp[1] + tmp[3] - 1;
  725. *xsize = r - l + 1;
  726. *ysize = t - b + 1;
  727. if (!*xsize || !*ysize)
  728. return (0);
  729. *pixbuf = (unsigned char *)G_malloc((*xsize) * (*ysize) * 4); /* G_fatal_error */
  730. if (!*pixbuf)
  731. return (0);
  732. glReadBuffer(GL_FRONT);
  733. /* OGLXXX lrectread: see man page for glReadPixels */
  734. glReadPixels(l, b, (r) - (l) + 1, (t) - (b) + 1, GL_RGBA,
  735. GL_UNSIGNED_BYTE, *pixbuf);
  736. return (1);
  737. }
  738. /*!
  739. \brief Get viewpoint
  740. \param tmp
  741. \param num
  742. \return 1
  743. */
  744. int gsd_getViewport(GLint tmp[4], GLint num[2])
  745. {
  746. /* Save current viewport to tmp */
  747. glGetIntegerv(GL_VIEWPORT, tmp);
  748. glGetIntegerv(GL_MAX_VIEWPORT_DIMS, num);
  749. return (1);
  750. }
  751. /*!
  752. \brief Write view
  753. \param pixbuf data buffer
  754. \param xsize,ysize picture dimension
  755. \return 0 on failure
  756. \return 1 on success
  757. */
  758. int gsd_writeView(unsigned char **pixbuf, unsigned int xsize,
  759. unsigned int ysize)
  760. {
  761. /* Malloc Buffer for image */
  762. *pixbuf = (unsigned char *)G_malloc(xsize * ysize * 4); /* G_fatal_error */
  763. if (!*pixbuf) {
  764. return (0);
  765. }
  766. /* Read image buffer */
  767. glReadBuffer(GL_FRONT);
  768. /* Read Pixels into Buffer */
  769. glReadPixels(0, 0, xsize, ysize, GL_RGBA, GL_UNSIGNED_BYTE, *pixbuf);
  770. return (1);
  771. }
  772. /*!
  773. \brief Specify pixel arithmetic
  774. \param yesno turn on/off
  775. */
  776. void gsd_blend(int yesno)
  777. {
  778. if (yesno) {
  779. glEnable(GL_BLEND);
  780. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  781. }
  782. else {
  783. glDisable(GL_BLEND);
  784. glBlendFunc(GL_ONE, GL_ZERO);
  785. }
  786. return;
  787. }
  788. /*!
  789. \brief Define clip plane
  790. \param num
  791. \param params
  792. */
  793. void gsd_def_clipplane(int num, double *params)
  794. {
  795. int wason = 0;
  796. /* OGLXXX see man page for glClipPlane equation */
  797. if (glIsEnabled(GL_CLIP_PLANE0 + (num))) {
  798. wason = 1;
  799. }
  800. glClipPlane(GL_CLIP_PLANE0 + (num), params);
  801. if (wason) {
  802. glEnable(GL_CLIP_PLANE0 + (num));
  803. }
  804. else {
  805. glDisable(GL_CLIP_PLANE0 + (num));
  806. }
  807. return;
  808. }
  809. /*!
  810. \brief Set clip plane
  811. \param num
  812. \param able
  813. */
  814. void gsd_set_clipplane(int num, int able)
  815. {
  816. /* OGLXXX see man page for glClipPlane equation */
  817. if (able) {
  818. glEnable(GL_CLIP_PLANE0 + (num));
  819. }
  820. else {
  821. glDisable(GL_CLIP_PLANE0 + (num));
  822. }
  823. return;
  824. }
  825. /*!
  826. \brief Finish
  827. Does nothing, only called from src.contrib/GMSL/NVIZ2.2/src/glwrappers.c
  828. */
  829. void gsd_finish(void)
  830. {
  831. return;
  832. }
  833. /*!
  834. \brief Set the viewport
  835. <i>l</i>, <i>b</i> specify the lower left corner of the viewport
  836. rectangle, in pixels.
  837. <i>r</i>, <i>t</i> specify the width and height of the viewport.
  838. \param l left
  839. \param r right
  840. \param b bottom
  841. \param t top
  842. */
  843. void gsd_viewport(int l, int r, int b, int t)
  844. {
  845. /* Screencoord */
  846. glViewport(l, b, r, t);
  847. return;
  848. }
  849. /*!
  850. \brief ADD
  851. First time called, gets a bunch of objects, then hands them back
  852. when needed
  853. \return -1 on failure
  854. \return number of objects
  855. */
  856. int gsd_makelist(void)
  857. {
  858. int i;
  859. if (numobjs) {
  860. if (numobjs < MAX_OBJS) {
  861. numobjs++;
  862. return (numobjs);
  863. }
  864. return (-1);
  865. }
  866. else {
  867. ObjList[0] = glGenLists(MAX_OBJS);
  868. for (i = 1; i < MAX_OBJS; i++) {
  869. ObjList[i] = ObjList[0] + i;
  870. }
  871. numobjs = 1;
  872. return (numobjs);
  873. }
  874. }
  875. /*!
  876. \brief ADD
  877. \param listno
  878. \param do_draw
  879. */
  880. void gsd_bgnlist(int listno, int do_draw)
  881. {
  882. if (do_draw) {
  883. glNewList(ObjList[listno], GL_COMPILE_AND_EXECUTE);
  884. }
  885. else {
  886. glNewList(ObjList[listno], GL_COMPILE);
  887. }
  888. return;
  889. }
  890. /*!
  891. \brief End list
  892. */
  893. void gsd_endlist(void)
  894. {
  895. glEndList();
  896. return;
  897. }
  898. /*!
  899. \brief Delete list
  900. \param listno
  901. \param range
  902. */
  903. void gsd_deletelist(GLuint listno, int range)
  904. {
  905. unsigned int i;
  906. for (i = 1; i < MAX_OBJS; i++) {
  907. if (i == listno) {
  908. glDeleteLists(ObjList[i], 1);
  909. numobjs--;
  910. if (numobjs < 1)
  911. numobjs = 1;
  912. return;
  913. }
  914. }
  915. }
  916. /*!
  917. \brief ADD
  918. \param listno
  919. */
  920. void gsd_calllist(int listno)
  921. {
  922. glCallList(ObjList[listno]);
  923. return;
  924. }
  925. /*!
  926. \brief ADD
  927. \param listno
  928. */
  929. void gsd_calllists(int listno)
  930. {
  931. int i;
  932. gsd_pushmatrix();
  933. for (i = 1; i < MAX_OBJS; i++) {
  934. glCallList(ObjList[i]);
  935. glFlush();
  936. }
  937. gsd_popmatrix();
  938. gsd_call_label();
  939. return;
  940. }