gsd_prim.c 20 KB

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