gsd_prim.c 21 KB

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