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