GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
Loading...
Searching...
No Matches
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
64static GLuint ObjList[MAX_OBJS];
65static int numobjs = 0;
66
67static int Shade;
68
69static float ogl_light_amb[MAX_LIGHTS][4];
70static float ogl_light_diff[MAX_LIGHTS][4];
71static float ogl_light_spec[MAX_LIGHTS][4];
72static float ogl_light_pos[MAX_LIGHTS][4];
73static float ogl_mat_amb[4];
74static float ogl_mat_diff[4];
75static float ogl_mat_spec[4];
76static float ogl_mat_emis[4];
77static 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 */
84void 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 */
98void 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 */
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 */
167void 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 */
187void 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 */
207void 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 */
241void 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 */
254void 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 */
267void gsd_linewidth(short n)
268{
269 glLineWidth((GLfloat)(n));
270
271 return;
272}
273
274/*!
275 \brief ADD
276 */
278{
279 glBegin(GL_QUAD_STRIP);
280
281 return;
282}
283
284/*!
285 \brief ADD
286 */
288{
289 glEnd();
290
291 return;
292}
293
294/*!
295 \brief ADD
296 */
297void gsd_bgntmesh(void)
298{
299 glBegin(GL_TRIANGLE_STRIP);
300
301 return;
302}
303
304/*!
305 \brief ADD
306 */
307void gsd_endtmesh(void)
308{
309 glEnd();
310
311 return;
312}
313
314/*!
315 \brief ADD
316 */
318{
319 glBegin(GL_TRIANGLE_STRIP);
320
321 return;
322}
323
324/*!
325 \brief ADD
326 */
328{
329 glEnd();
330
331 return;
332}
333
334/*!
335 \brief ADD
336 */
337void gsd_bgntfan(void)
338{
339 glBegin(GL_TRIANGLE_FAN);
340
341 return;
342}
343
344/*!
345 \brief ADD
346 */
347void gsd_endtfan(void)
348{
349 glEnd();
350
351 return;
352}
353
354/*!
355 \brief ADD
356 */
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 */
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 */
388{
389 glEnd();
390
391 return;
392}
393
394/*!
395 \brief Begin line
396 */
397void 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 */
407void 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 */
419void 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 */
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 */
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 */
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 */
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 */
502{
503 glPopMatrix();
504
505 return;
506}
507
508/*!
509 \brief Push the current matrix stack
510 */
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 */
525void 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 */
539void 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 */
554void gsd_getwindow(int *window, int *viewport, double *modelMatrix,
555 double *projMatrix)
556{
558 gsd_do_scale(1);
559
560 glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
561 glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
562 glGetIntegerv(GL_VIEWPORT, viewport);
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 */
585int 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 */
605void 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 */
657void 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 */
673void 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 */
686void 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 */
698void 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 */
803void 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 */
836void 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 */
877void 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 */
902int 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 */
950int 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 */
969int 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 */
994void 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 */
1014void 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 */
1041void 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 */
1059void 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 */
1077void 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 */
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 */
1125void 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 */
1140void 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 */
1153void 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 */
1173void gsd_calllist(int listno)
1174{
1175 glCallList(ObjList[listno]);
1176
1177 return;
1178}
1179
1180/*!
1181 \brief ADD
1182
1183 \param listno [unused]
1184 */
1185void gsd_calllists(int listno UNUSED)
1186{
1187 int i;
1188
1190 for (i = 1; i < MAX_OBJS; i++) {
1191 glCallList(ObjList[i]);
1192 glFlush();
1193 }
1194 gsd_popmatrix();
1195
1197
1198 return;
1199}
double b
double l
double t
double r
void G_message(const char *msg,...)
Print a message to stderr.
Definition gis/error.c:89
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition gis/error.c:203
void gsd_call_label(void)
Call display list and draw defined labels – called from gsd_prim (gsd_call_lists)
Definition gsd_label.c:119
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
void gsd_do_scale(int doexag)
Set current scale.
Definition gsd_views.c:355
float g
Definition named_colr.c:7
#define X(j)
#define x
#define Y(j)