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