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