GRASS GIS 8 Programmer's Manual 8.2.0(2022)-exported
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
63static GLuint ObjList[MAX_OBJS];
64static int numobjs = 0;
65
66static int Shade;
67
68static float ogl_light_amb[MAX_LIGHTS][4];
69static float ogl_light_diff[MAX_LIGHTS][4];
70static float ogl_light_spec[MAX_LIGHTS][4];
71static float ogl_light_pos[MAX_LIGHTS][4];
72static float ogl_mat_amb[4];
73static float ogl_mat_diff[4];
74static float ogl_mat_spec[4];
75static float ogl_mat_emis[4];
76static 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 */
83void 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 */
97void 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 */
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 */
166void 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 */
186void 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 */
206void 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 */
240void 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 */
253void 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 */
266void gsd_linewidth(short n)
267{
268 glLineWidth((GLfloat) (n));
269
270 return;
271}
272
273/*!
274 \brief ADD
275 */
277{
278 glBegin(GL_QUAD_STRIP);
279
280 return;
281}
282
283/*!
284 \brief ADD
285 */
287{
288 glEnd();
289
290 return;
291}
292
293/*!
294 \brief ADD
295 */
296void gsd_bgntmesh(void)
297{
298 glBegin(GL_TRIANGLE_STRIP);
299
300 return;
301}
302
303/*!
304 \brief ADD
305 */
306void gsd_endtmesh(void)
307{
308 glEnd();
309
310 return;
311}
312
313/*!
314 \brief ADD
315 */
317{
318 glBegin(GL_TRIANGLE_STRIP);
319
320 return;
321}
322
323/*!
324 \brief ADD
325 */
327{
328 glEnd();
329
330 return;
331}
332
333/*!
334 \brief ADD
335 */
336void gsd_bgntfan(void)
337{
338 glBegin(GL_TRIANGLE_FAN);
339
340 return;
341}
342
343/*!
344 \brief ADD
345 */
346void gsd_endtfan(void)
347{
348 glEnd();
349
350 return;
351}
352
353/*!
354 \brief ADD
355 */
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 */
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 */
387{
388 glEnd();
389
390 return;
391}
392
393/*!
394 \brief Begin line
395 */
396void 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 */
406void 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 */
418void 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 */
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 */
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 */
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 */
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 */
501{
502 glPopMatrix();
503
504 return;
505}
506
507/*!
508 \brief Push the current matrix stack
509 */
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 */
524void 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 */
538void 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 */
553void gsd_getwindow(int *window, int *viewport, double *modelMatrix,
554 double *projMatrix)
555{
557 gsd_do_scale(1);
558
559 glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
560 glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
561 glGetIntegerv(GL_VIEWPORT, viewport);
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 */
585int 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 */
609void 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 */
660void 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 */
676void 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 */
689void 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 */
701void 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 */
806void 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 */
839void 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 */
880void 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 */
905int 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 */
952int 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 */
971int 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 */
996void 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 */
1016void 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 */
1043void 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 */
1061void 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 */
1079void 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 */
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 */
1128void 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 */
1143void gsd_endlist(void)
1144{
1145 glEndList();
1146
1147 return;
1148}
1149
1150/*!
1151 \brief Delete list
1152
1153 \param listno
1154 \param range
1155 */
1156void 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 */
1176void gsd_calllist(int listno)
1177{
1178 glCallList(ObjList[listno]);
1179
1180 return;
1181}
1182
1183
1184/*!
1185 \brief ADD
1186
1187 \param listno
1188 */
1189void gsd_calllists(int listno)
1190{
1191 int i;
1192
1194 for (i = 1; i < MAX_OBJS; i++) {
1195 glCallList(ObjList[i]);
1196 glFlush();
1197 }
1198 gsd_popmatrix();
1199
1201
1202 return;
1203}
double b
double l
double t
double r
void G_message(const char *msg,...)
Print a message to stderr.
Definition: gis/error.c:90
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
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_set_clipplane(int num, int able)
Set clip plane.
Definition: gsd_prim.c:1043
void gsd_endlist(void)
End list.
Definition: gsd_prim.c:1143
void gsd_viewport(int l, int r, int b, int t)
Set the viewport.
Definition: gsd_prim.c:1079
void gsd_endtstrip(void)
ADD.
Definition: gsd_prim.c:326
void gsd_endtfan(void)
ADD.
Definition: gsd_prim.c:346
void gsd_endtmesh(void)
ADD.
Definition: gsd_prim.c:306
void gsd_swaptmesh(void)
ADD.
Definition: gsd_prim.c:356
void gsd_backface(int n)
ADD.
Definition: gsd_prim.c:253
void gsd_pushmatrix(void)
Push the current matrix stack.
Definition: gsd_prim.c:510
int gsd_getViewport(GLint tmp[4], GLint num[2])
Get viewpoint.
Definition: gsd_prim.c:952
void gsd_calllist(int listno)
ADD.
Definition: gsd_prim.c:1176
void gsd_zwritemask(unsigned long n)
Write out z-mask.
Definition: gsd_prim.c:240
void gsd_deflight(int num, struct lightdefs *vals)
Define light.
Definition: gsd_prim.c:839
void gsd_vert_func(float *pt)
ADD.
Definition: gsd_prim.c:689
void gsd_bgnqstrip(void)
ADD.
Definition: gsd_prim.c:276
void gsd_switchlight(int num, int on)
Switch light on/off.
Definition: gsd_prim.c:880
#define INT_TO_GRN(i, g)
Definition: gsd_prim.c:53
void gsd_litvert_func(float *norm, unsigned long col, float *pt)
Set the current normal vector & specify vertex.
Definition: gsd_prim.c:660
#define border
Definition: gsd_prim.c:61
void gsd_colormode(int cm)
Set color mode.
Definition: gsd_prim.c:97
void gsd_bgnpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:371
int gsd_writeView(unsigned char **pixbuf, unsigned int xsize, unsigned int ysize)
Write view.
Definition: gsd_prim.c:971
void gsd_bgntstrip(void)
ADD.
Definition: gsd_prim.c:316
void gsd_blend(int yesno)
Specify pixel arithmetic.
Definition: gsd_prim.c:996
void gsd_init_lightmodel(void)
Initialize model light.
Definition: gsd_prim.c:722
int gsd_getshademodel(void)
Get shaded model.
Definition: gsd_prim.c:437
void gsd_bgnlist(int listno, int do_draw)
ADD.
Definition: gsd_prim.c:1128
int gsd_makelist(void)
ADD.
Definition: gsd_prim.c:1096
void gsd_swapbuffers(void)
Swap buffers.
Definition: gsd_prim.c:481
void gsd_endqstrip(void)
ADD.
Definition: gsd_prim.c:286
void gsd_sphere(float *center, float siz)
ADD.
Definition: gsd_prim.c:206
void show_colormode(void)
Print color mode to stderr.
Definition: gsd_prim.c:150
#define INT_TO_RED(i, r)
Definition: gsd_prim.c:52
int gsd_getimage(unsigned char **pixbuf, unsigned int *xsize, unsigned int *ysize)
Get image of current GL screen.
Definition: gsd_prim.c:905
#define INT_TO_BLU(i, b)
Definition: gsd_prim.c:54
void gsd_backbuffer(void)
Draw to the back buffer.
Definition: gsd_prim.c:469
#define MAX_OBJS
Definition: gsd_prim.c:57
void gsd_popmatrix(void)
Pop the current matrix stack.
Definition: gsd_prim.c:500
void gsd_flush(void)
Mostly for flushing drawing commands across a network.
Definition: gsd_prim.c:83
void gsd_def_clipplane(int num, double *params)
Define clip plane.
Definition: gsd_prim.c:1016
void gsd_endline(void)
End line.
Definition: gsd_prim.c:406
void gsd_finish(void)
Finish.
Definition: gsd_prim.c:1061
void gsd_calllists(int listno)
ADD.
Definition: gsd_prim.c:1189
void gsd_circ(float x, float y, float rad)
ADD.
Definition: gsd_prim.c:166
void gsd_bgntfan(void)
ADD.
Definition: gsd_prim.c:336
void gsd_deletelist(GLuint listno, int range)
Delete list.
Definition: gsd_prim.c:1156
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:609
void gsd_bgnline(void)
Begin line.
Definition: gsd_prim.c:396
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_translate(float dx, float dy, float dz)
Multiply the current matrix by a translation matrix.
Definition: gsd_prim.c:538
void gsd_bgntmesh(void)
ADD.
Definition: gsd_prim.c:296
void gsd_disc(float x, float y, float z, float rad)
ADD.
Definition: gsd_prim.c:186
void gsd_getwindow(int *window, int *viewport, double *modelMatrix, double *projMatrix)
Get viewport.
Definition: gsd_prim.c:553
#define INT_TO_ALP(i, a)
Definition: gsd_prim.c:55
void gsd_litvert_func2(float *norm, unsigned long col, float *pt)
ADD.
Definition: gsd_prim.c:676
void gsd_color_func(unsigned int col)
Set current color.
Definition: gsd_prim.c:701
void gsd_shademodel(int shade)
Set shaded model.
Definition: gsd_prim.c:418
void gsd_bothbuffers(void)
Draw to the front and back buffers.
Definition: gsd_prim.c:445
void gsd_frontbuffer(void)
Draw to the front buffer.
Definition: gsd_prim.c:457
void gsd_endpolygon(void)
Delimit the vertices of a primitive or a group of like primitives.
Definition: gsd_prim.c:386
void gsd_linewidth(short n)
Set width of rasterized lines.
Definition: gsd_prim.c:266
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_do_scale(int doexag)
Set current scale.
Definition: gsd_views.c:355
float g
Definition: named_colr.c:8
#define X(j)
#define x
#define Y(j)