1 /* Steven Andrews, 2/03.
2 OpenGL library of useful routines.
3 See documentation called opengl2_doc.doc.
4 Copyright 2003-2007 by Steven Andrews. This work is distributed under the terms
5 of the Gnu Lesser General Public License (LGPL). */
6
7 #include <stdio.h>
8 #include <math.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "opengl2.h"
12 #include "math2.h"
13 #include "random2.h"
14 #include "string2.h"
15
16 #define Fix2DAspectDefault 0
17 #define TiffNameDefault "OpenGL"
18 #define TiffNumberDefault 1
19 #define TiffNumMaxDefault 999
20 #define RotateAngleDefault 5.0
21
22 void ChangeSize(int w,int h);
23 void KeyPush(unsigned char key,int x,int y);
24 void SpecialKeyPush2(unsigned char key,int x,int y);
25 void SpecialKeyPush(int key,int x,int y);
26 int WriteTIFF(const char *filename,const char *description,int x,int y,int width,int height,int compression);
27
28 GLfloat ClipSize,ClipMidx,ClipMidy,ClipMidz;
29 GLfloat ClipLeft,ClipRight,ClipBot,ClipTop,ClipBack,ClipFront;
30 GLfloat FieldOfView,Near,Aspect,Zoom;
31 GLfloat PixWide,PixHigh;
32 int Gl2PauseState,Dimension;
33 GLfloat Xtrans,Ytrans;
34 char TiffName[STRCHAR]=TiffNameDefault;
35 int Fix2DAspect=Fix2DAspectDefault;
36 int TiffNumber=TiffNumberDefault;
37 int TiffNumMax=TiffNumMaxDefault;
38 GLfloat RotateAngle=RotateAngleDefault;
39 void (*FreeFunc)(void*)=NULL;
40 void *FreePointer=NULL;
41
42
43 /* ***************************************** */
44 /* ************* Local functions *********** */
45 /* ***************************************** */
46
47
48 /* ChangeSize */
ChangeSize(int w,int h)49 void ChangeSize(int w,int h) {
50 #ifdef __gl_h_
51 GLfloat clipheight,clipwidth;
52 GLfloat nearold,m[16];
53
54 PixWide=w;
55 PixHigh=h;
56 if(h==0) h=1;
57 glViewport(0,0,w,h);
58 if(Dimension<3 && Fix2DAspect) {
59 if(w<=h) {
60 clipheight=ClipSize/Zoom*h/w;
61 clipwidth=ClipSize/Zoom; }
62 else {
63 clipheight=ClipSize/Zoom;
64 clipwidth=ClipSize/Zoom*w/h; }
65 glMatrixMode(GL_PROJECTION);
66 glLoadIdentity();
67 glOrtho(ClipLeft,ClipLeft+clipwidth,ClipBot,ClipBot+clipheight,ClipFront,ClipBack);
68 glMatrixMode(GL_MODELVIEW);
69 glLoadIdentity(); }
70 else if(Dimension<3) {
71 glMatrixMode(GL_PROJECTION);
72 glLoadIdentity();
73 glOrtho(ClipLeft,ClipRight,ClipBot,ClipTop,ClipFront,ClipBack);
74 glMatrixMode(GL_MODELVIEW);
75 glLoadIdentity(); }
76 else {
77 Aspect=1.0*w/h;
78 nearold=Near;
79 if(w>=h) Near=ClipSize/2.0/tan(FieldOfView*PI/180.0/2.0);
80 else Near=ClipSize/2.0/tan(FieldOfView*Aspect*PI/180.0/2.0);
81 glMatrixMode(GL_PROJECTION);
82 glLoadIdentity();
83 gluPerspective(FieldOfView,Aspect,Near,ClipSize+Near);
84 glMatrixMode(GL_MODELVIEW);
85 glGetFloatv(GL_MODELVIEW_MATRIX,m);
86 glLoadIdentity();
87 glTranslatef(0,0,nearold-Near);
88 glMultMatrixf(m); }
89 #endif
90 return; }
91
92
93
94 /* KeyPush */
KeyPush(unsigned char key,int x,int y)95 void KeyPush(unsigned char key,int x,int y) {
96 #ifdef __gl_h_
97 GLint viewport[4],w,h;
98 char name[2*STRCHAR],str[2*STRCHAR];
99 GLfloat clipheight,clipwidth;
100
101 (void)x;
102 (void)y;
103 glMatrixMode(GL_MODELVIEW);
104 if(key=='Q') {
105 if(Gl2PauseState==2) {
106 if(FreeFunc) (*FreeFunc)(FreePointer);
107 exit(0);
108 }
109 else Gl2PauseState=2; }
110 else if(key==' ' && Gl2PauseState==0) Gl2PauseState=1;
111 else if(key==' ' && Gl2PauseState==1) Gl2PauseState=0;
112 else if(key=='T' && TiffNumber<=TiffNumMax) {
113 glGetIntegerv(GL_VIEWPORT,viewport);
114 w=viewport[2];
115 h=viewport[3];
116 snprintf(str,2*STRCHAR,"%s%%0%ii.tif",TiffName,(int)log10((double)TiffNumMax)+1);
117 str[2*STRCHAR-1]='\0';
118 snprintf(name,STRCHAR,str,TiffNumber);
119 name[2*STRCHAR-1]='\0';
120 WriteTIFF(name,"OpenGL picture",0,0,w,h,-1);
121 TiffNumber++; }
122 else if(key=='z' && Dimension==3) glRotatef(RotateAngle,0,0,1);
123 else if(key=='Z' && Dimension==3) glRotatef(-RotateAngle,0,0,1);
124 else if(key=='x' && Dimension==3) glRotatef(RotateAngle,1,0,0);
125 else if(key=='X' && Dimension==3) glRotatef(-RotateAngle,1,0,0);
126 else if(key=='y' && Dimension==3) glRotatef(RotateAngle,0,1,0);
127 else if(key=='Y' && Dimension==3) glRotatef(-RotateAngle,0,1,0);
128 else if(Dimension<3) {
129 if(key=='0') {
130 Zoom=1;
131 Xtrans=Ytrans=0; }
132 else if(key=='=') Zoom*=1.05;
133 else if(key=='-') Zoom/=1.05;
134 ClipLeft=ClipMidx-Xtrans-ClipSize/2.0/Zoom;
135 ClipRight=ClipMidx-Xtrans+ClipSize/2.0/Zoom;
136 ClipBot=ClipMidy-Ytrans-ClipSize/2.0/Zoom;
137 ClipTop=ClipMidy-Ytrans+ClipSize/2.0/Zoom;
138 ClipBack=ClipMidz-ClipSize/2.0/Zoom;
139 ClipFront=ClipMidz+ClipSize/2.0/Zoom;
140 glMatrixMode(GL_PROJECTION);
141 glLoadIdentity();
142 if(Fix2DAspect) {
143 glGetIntegerv(GL_VIEWPORT,viewport);
144 w=viewport[2];
145 h=viewport[3];
146 if(w<=h) {
147 clipheight=ClipSize/Zoom*h/w;
148 clipwidth=ClipSize/Zoom; }
149 else {
150 clipheight=ClipSize/Zoom;
151 clipwidth=ClipSize/Zoom*w/h; }
152 glOrtho(ClipLeft,ClipLeft+clipwidth,ClipBot,ClipBot+clipheight,ClipFront,ClipBack); }
153 else
154 glOrtho(ClipLeft,ClipRight,ClipBot,ClipTop,ClipFront,ClipBack);
155 glMatrixMode(GL_MODELVIEW);
156 glLoadIdentity(); }
157
158 else if(Dimension==3) {
159 if(key=='0') {
160 glGetIntegerv(GL_VIEWPORT,viewport);
161 w=viewport[2];
162 h=viewport[3];
163 FieldOfView=45;
164 Xtrans=Ytrans=0;
165 if(w>=h) Near=ClipSize/2.0/tan(FieldOfView*PI/180.0/2.0);
166 else Near=ClipSize/2.0/tan(FieldOfView*Aspect*PI/180.0/2.0);
167 glMatrixMode(GL_PROJECTION);
168 glLoadIdentity();
169 gluPerspective(FieldOfView,Aspect,Near,ClipSize+Near);
170 glMatrixMode(GL_MODELVIEW);
171 glLoadIdentity();
172 glTranslatef(-ClipMidx,-ClipMidy,-ClipMidz);
173 glTranslatef(0,0,-ClipSize/2.0-Near); }
174 else if(key=='=') {
175 FieldOfView/=1.05;
176 glMatrixMode(GL_PROJECTION);
177 glLoadIdentity();
178 gluPerspective(FieldOfView,Aspect,Near,ClipSize+Near);
179 glMatrixMode(GL_MODELVIEW); }
180 else if(key=='-') {
181 FieldOfView*=1.05;
182 if(FieldOfView>180) FieldOfView=180;
183 glMatrixMode(GL_PROJECTION);
184 glLoadIdentity();
185 gluPerspective(FieldOfView,Aspect,Near,ClipSize+Near);
186 glMatrixMode(GL_MODELVIEW); }}
187 #endif
188 return; }
189
190
191
192 /* SpecialKeyPush2 */
SpecialKeyPush2(unsigned char key,int x,int y)193 void SpecialKeyPush2(unsigned char key,int x,int y) {
194 #ifdef __gl_h_
195 GLfloat m[16];
196 GLint viewport[4],w,h;
197 GLfloat clipheight,clipwidth;
198
199 (void)x;
200 (void)y;
201 if(Dimension<3) {
202 if(key=='D') Ytrans-=(ClipRight-ClipLeft)/100;
203 else if(key=='U') Ytrans+=(ClipRight-ClipLeft)/100;
204 else if(key=='R') Xtrans+=(ClipRight-ClipLeft)/100;
205 else if(key=='L') Xtrans-=(ClipRight-ClipLeft)/100;
206 ClipLeft=ClipMidx-Xtrans-ClipSize/2.0/Zoom;
207 ClipRight=ClipMidx-Xtrans+ClipSize/2.0/Zoom;
208 ClipBot=ClipMidy-Ytrans-ClipSize/2.0/Zoom;
209 ClipTop=ClipMidy-Ytrans+ClipSize/2.0/Zoom;
210 ClipBack=ClipMidz-ClipSize/2.0/Zoom;
211 ClipFront=ClipMidz+ClipSize/2.0/Zoom;
212 glMatrixMode(GL_PROJECTION);
213 glLoadIdentity();
214 if(Fix2DAspect) {
215 glGetIntegerv(GL_VIEWPORT,viewport);
216 w=viewport[2];
217 h=viewport[3];
218 if(w<=h) {
219 clipheight=ClipSize/Zoom*h/w;
220 clipwidth=ClipSize/Zoom; }
221 else {
222 clipheight=ClipSize/Zoom;
223 clipwidth=ClipSize/Zoom*w/h; }
224 glOrtho(ClipLeft,ClipLeft+clipwidth,ClipBot,ClipBot+clipheight,ClipFront,ClipBack); }
225 else
226 glOrtho(ClipLeft,ClipRight,ClipBot,ClipTop,ClipFront,ClipBack);
227 glMatrixMode(GL_MODELVIEW);
228 glLoadIdentity(); }
229 else if(Dimension==3) {
230 glMatrixMode(GL_MODELVIEW);
231 glGetFloatv(GL_MODELVIEW_MATRIX,m);
232 glLoadIdentity();
233 if(strchr("durl",key)) {
234 glTranslatef(Xtrans,Ytrans,-(Near+ClipSize/2.0));
235 if(key=='d') glRotatef(RotateAngle,1,0,0);
236 else if(key=='u') glRotatef(-RotateAngle,1,0,0);
237 else if(key=='r') glRotatef(RotateAngle,0,1,0);
238 else if(key=='l') glRotatef(-RotateAngle,0,1,0);
239 glTranslatef(-Xtrans,-Ytrans,+(Near+ClipSize/2.0)); }
240 else if(strchr("DURL",key)) {
241 glTranslatef(-Xtrans,-Ytrans,-(Near+ClipSize/2.0));
242 if(key=='D') Ytrans-=ClipSize/100;
243 else if(key=='U') Ytrans+=ClipSize/100;
244 else if(key=='R') Xtrans+=ClipSize/100;
245 else if(key=='L') Xtrans-=ClipSize/100;
246 glTranslatef(Xtrans,Ytrans,+(Near+ClipSize/2.0)); }
247 glMultMatrixf(m); }
248 #endif
249 return; }
250
251
252
253 /* SpecialKeyPush */
SpecialKeyPush(int key,int x,int y)254 void SpecialKeyPush(int key,int x,int y) {
255 #ifdef __gl_h_
256 int modify;
257
258 modify=glutGetModifiers();
259 if(!modify) {
260 if(key==GLUT_KEY_DOWN) SpecialKeyPush2('d',x,y);
261 else if(key==GLUT_KEY_UP) SpecialKeyPush2('u',x,y);
262 else if(key==GLUT_KEY_RIGHT) SpecialKeyPush2('r',x,y);
263 else if(key==GLUT_KEY_LEFT) SpecialKeyPush2('l',x,y); }
264 else {
265 if(key==GLUT_KEY_DOWN) SpecialKeyPush2('D',x,y);
266 else if(key==GLUT_KEY_UP) SpecialKeyPush2('U',x,y);
267 else if(key==GLUT_KEY_RIGHT) SpecialKeyPush2('R',x,y);
268 else if(key==GLUT_KEY_LEFT) SpecialKeyPush2('L',x,y); }
269 #endif
270 return; }
271
272
273
274 /* The following code was modified from a program called writetiff.c that was
275 written and copyrighted by Mark Kilgard, 1997. This function requires the use
276 of the libtiff library that was written by Sam Leffler and can be downloaded
277 from www.libtiff.org. */
WriteTIFF(const char * filename,const char * description,int x,int y,int width,int height,int compression)278 int WriteTIFF(const char *filename,const char *description,int x,int y,int width,int height,int compression) {
279 #if defined _TIFFIO_ && defined __gl_h_
280 TIFF *file;
281 GLubyte *image,*p;
282 int i;
283
284 if(compression==-1) compression=COMPRESSION_PACKBITS;
285 file=TIFFOpen(filename,"w");
286 if(!file) return 1;
287 image=(GLubyte*)malloc(width*height*sizeof(GLubyte)*3);
288 if(!image) return 1;
289 glPixelStorei(GL_PACK_ALIGNMENT,1);
290 glReadPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE,image);
291 TIFFSetField(file,TIFFTAG_IMAGEWIDTH,(unsigned int)width);
292 TIFFSetField(file,TIFFTAG_IMAGELENGTH,(unsigned int)height);
293 TIFFSetField(file,TIFFTAG_BITSPERSAMPLE,8);
294 TIFFSetField(file,TIFFTAG_COMPRESSION,compression);
295 TIFFSetField(file,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_RGB);
296 TIFFSetField(file,TIFFTAG_SAMPLESPERPIXEL,3);
297 TIFFSetField(file,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
298 TIFFSetField(file,TIFFTAG_ROWSPERSTRIP,1);
299 TIFFSetField(file,TIFFTAG_IMAGEDESCRIPTION,description);
300 p=image;
301 for(i=height-1;i>=0;i--) {
302 if(TIFFWriteScanline(file,p,i,0)<0) {
303 free(image);
304 TIFFClose(file);
305 return 1; }
306 p+=width*sizeof(GLubyte)*3; }
307 TIFFClose(file);
308 free(image);
309 return 0;
310 #else
311 return 2;
312 #endif
313 }
314
315
316
317 /* **************************************************** */
318 /* ********** Externally accessible routines ********** */
319 /* **************************************************** */
320
321
322 /* gl2Double2GLfloat */
gl2Double2GLfloat(double * input,GLfloat * output,int n)323 GLfloat* gl2Double2GLfloat(double *input,GLfloat *output,int n) {
324 int i;
325
326 for(i=0;i<n;i++)
327 output[i]=(GLfloat)input[i];
328 return output; }
329
330
331 /* gl2Initialize */
gl2Initialize(char * wname,float xlo,float xhi,float ylo,float yhi,float zlo,float zhi)332 void gl2Initialize(char *wname,float xlo,float xhi,float ylo,float yhi,float zlo,float zhi) {
333 #ifdef __gl_h_
334 if(ylo==yhi && zlo==zhi) Dimension=1;
335 else if(zlo==zhi) Dimension=2;
336 else Dimension=3;
337 ClipSize=1.05*sqrt((xhi-xlo)*(xhi-xlo)+(yhi-ylo)*(yhi-ylo)+(zhi-zlo)*(zhi-zlo));
338 if(ClipSize==0) ClipSize=1.0;
339 ClipMidx=(xhi-xlo)/2.0+xlo;
340 ClipMidy=(yhi-ylo)/2.0+ylo;
341 ClipMidz=(zhi-zlo)/2.0+zlo;
342 ClipLeft=ClipMidx-ClipSize/2.0;
343 ClipRight=ClipMidx+ClipSize/2.0;
344 ClipBot=ClipMidy-ClipSize/2.0;
345 ClipTop=ClipMidy+ClipSize/2.0;
346 ClipBack=ClipMidz-ClipSize/2.0;
347 ClipFront=ClipMidz+ClipSize/2.0;
348 if(Dimension==2 && !Fix2DAspect) {
349 ClipLeft=xlo;
350 ClipRight=xhi;
351 ClipBot=ylo;
352 ClipTop=yhi; }
353 FieldOfView=45;
354 Zoom=1;
355 Xtrans=Ytrans=0;
356 Near=-ClipSize/2.0;
357 Aspect=1.0;
358 Gl2PauseState=0;
359
360 if(Dimension<3) glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
361 else glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
362
363 // position opengl window
364 int w = 400, h = 400;
365 int xmaxpix=glutGet(GLUT_SCREEN_WIDTH);
366 int ymaxpix=glutGet(GLUT_SCREEN_HEIGHT);
367 glutInitWindowSize(w, h);
368 glutInitWindowPosition((xmaxpix- w)/2, (ymaxpix-h)/2);
369
370 glutCreateWindow(wname?wname:"OpenGL");
371 glutReshapeFunc(ChangeSize);
372 glutKeyboardFunc(KeyPush);
373 glutSpecialFunc(SpecialKeyPush);
374 glClearColor(1,1,1,1);
375 glColor3f(0,0,0);
376 glMatrixMode(GL_MODELVIEW);
377 glLoadIdentity();
378 glTranslatef(-ClipMidx,-ClipMidy,-ClipMidz);
379 if(Dimension==3) {
380 glEnable(GL_DEPTH_TEST); }
381 #endif
382 return; }
383
384
385
386 /* gl2glutInit */
gl2glutInit(int * argc,char ** argv)387 void gl2glutInit(int *argc,char **argv) {
388 #ifdef __gl_h_
389 static int done=0;
390 int defaultc=1;
391 char **defaultv;
392
393 if(done) return;
394 done=1;
395 if(argc && argv)
396 glutInit(argc,argv); // ?? This is where the code crashes when using _freeglut
397 else {
398 defaultv=(char**) calloc(1,sizeof(char*));
399 if(!defaultv) return;
400 defaultv[0]=(char*) calloc(STRCHAR,sizeof(char));
401 if(!defaultv[0]) return;
402 strcpy(defaultv[0],"default");
403 glutInit(&defaultc,(char**) defaultv);
404 free(defaultv[0]);
405 free(defaultv); }
406
407 // When a window is closed by use, return from
408 // the main loop and do not terminate the
409 // program.
410 /** glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); */
411 /** glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); */
412 #endif
413 return; }
414
415
416
417 /* gl2State */
gl2State(int state)418 int gl2State(int state) {
419 if(state>=0) Gl2PauseState=state;
420 return Gl2PauseState; }
421
422
423 /* gl2GetNumber */
gl2GetNumber(const char * variable)424 float gl2GetNumber(const char *variable) {
425 float value;
426
427 if(!strcmp(variable,"ClipSize")) value=ClipSize;
428 else if(!strcmp(variable,"ClipMidx")) value=ClipMidx;
429 else if(!strcmp(variable,"ClipMidy")) value=ClipMidy;
430 else if(!strcmp(variable,"ClipMidz")) value=ClipMidz;
431 else if(!strcmp(variable,"ClipLeft")) value=ClipLeft;
432 else if(!strcmp(variable,"ClipRight")) value=ClipRight;
433 else if(!strcmp(variable,"ClipBot")) value=ClipBot;
434 else if(!strcmp(variable,"ClipTop")) value=ClipTop;
435 else if(!strcmp(variable,"ClipBack")) value=ClipBack;
436 else if(!strcmp(variable,"ClipFront")) value=ClipFront;
437 else if(!strcmp(variable,"FieldOfView")) value=FieldOfView;
438 else if(!strcmp(variable,"Zoom")) value=Zoom;
439 else if(!strcmp(variable,"Near")) value=Near;
440 else if(!strcmp(variable,"Aspect")) value=Aspect;
441 else if(!strcmp(variable,"PixWide")) value=PixWide;
442 else if(!strcmp(variable,"PixHigh")) value=PixHigh;
443 else if(!strcmp(variable,"Gl2PauseState")) value=(float) Gl2PauseState;
444 else if(!strcmp(variable,"Dimension")) value=(float) Dimension;
445 else if(!strcmp(variable,"Xtrans")) value=Xtrans;
446 else if(!strcmp(variable,"Ytrans")) value=Ytrans;
447 else if(!strcmp(variable,"Fix2DAspect")) value=(float) Fix2DAspect;
448 else if(!strcmp(variable,"TiffNumber")) value=(float) TiffNumber;
449 else if(!strcmp(variable,"TiffNumMax")) value=(float) TiffNumMax;
450 else if(!strcmp(variable,"RotateAngle")) value=RotateAngle;
451 else if(!strcmp(variable,"TiffNumberDefault")) value=(float) TiffNumberDefault;
452 else if(!strcmp(variable,"TiffNumMaxDefault")) value=(float) TiffNumMaxDefault;
453 else if(!strcmp(variable,"RotateAngleDefault")) value=RotateAngleDefault;
454 else if(!strcmp(variable,"Fix2DAspectDefault")) value=(float) Fix2DAspectDefault;
455 else value=0;
456 return value; }
457
458
459 /* gl2GetString */
gl2GetString(const char * option,char * string)460 char *gl2GetString(const char *option,char *string) {
461 if(!strcmp(option,"TiffName"))
462 strncpy(string,TiffName,STRCHAR);
463 else if(!strcmp(option,"TiffNameDefault"))
464 strncpy(string,TiffNameDefault,STRCHAR);
465 else
466 strncpy(string,"error",STRCHAR);
467 return string; }
468
469
470 /* gl2SetOptionInt */
gl2SetOptionInt(const char * option,int value)471 int gl2SetOptionInt(const char *option,int value) {
472 if(!strcmp(option,"Fix2DAspect")) {
473 if(value>=0) Fix2DAspect=value;
474 else value=Fix2DAspect; }
475 else if(!strcmp(option,"TiffNumber")) {
476 if(value>=0) TiffNumber=value;
477 else value=TiffNumber; }
478 else if(!strcmp(option,"TiffNumMax")) {
479 if(value>=0) TiffNumMax=value;
480 else value=TiffNumMax; }
481 else if(!strcmp(option,"Dimension")) {
482 value=Dimension; }
483 else value=-1;
484 return value; }
485
486
487 /* gl2SetOptionFlt */
gl2SetOptionFlt(const char * option,float value)488 float gl2SetOptionFlt(const char *option,float value) {
489 if(!strcmp(option,"RotateAngle")) {
490 if(value>0) RotateAngle=(GLfloat) value;
491 else value=(float) RotateAngle; }
492 else value=-1;
493 return value; }
494
495
496 /* gl2SetOptionStr */
gl2SetOptionStr(const char * option,const char * value)497 void gl2SetOptionStr(const char *option,const char *value) {
498 if(!strcmp(option,"TiffName")) {
499 if(value) strncpy(TiffName,value,STRCHAR-1);
500 else strncpy(TiffName,TiffNameDefault,STRCHAR-1);
501 TiffName[STRCHAR-1]='\0'; }
502 return; }
503
504
505 /* gl2SetOptionVoid */
gl2SetOptionVoid(const char * option,void * value)506 void *gl2SetOptionVoid(const char *option,void *value) {
507 if(!strcmp(option,"FreeFunc")) {
508 if(value) FreeFunc=(void(*)(void*))value;
509 else value=(void*) FreeFunc; }
510 else if(!strcmp(option,"FreePointer")) {
511 if(value) FreePointer=value;
512 else value=FreePointer; }
513 else value=NULL;
514 return (void*)value; }
515
516
517 /* gl2SetKeyPush */
gl2SetKeyPush(unsigned char key)518 void gl2SetKeyPush(unsigned char key) {
519 if(strchr(" QT0=-xyzXYZ",key)) KeyPush(key,0,0);
520 else if(strchr("durlDURL",key)) SpecialKeyPush2(key,0,0);
521 return; }
522
523
524 /* gl2SetColor */
gl2SetColor(char c)525 void gl2SetColor(char c) {
526 #ifdef __gl_h_
527 if(c=='A' || c=='a') glColor3ub(0x70,0xdb,0x93); /* aqua */
528 else if(c=='B' || c=='b' || c=='6') glColor3ub(0x00,0x00,0xff); /* blue */
529 else if(c=='C' || c=='c') glColor3ub(0x00,0xff,0xff); /* cyan */
530 else if(c=='D' || c=='d') glColor3ub(0x80,0x00,0x00); /* dark red */
531 else if(c=='E' || c=='e' || c=='8') glColor3ub(0x80,0x80,0x80); /* grey */
532 else if(c=='F' || c=='f') glColor3ub(0xff,0x6e,0xc7); /* fuchsia */
533 else if(c=='G' || c=='g') glColor3ub(0x00,0xff,0x00); /* green */
534 else if(c=='H' || c=='h' || c=='5') glColor3ub(0x00,0x80,0x00); /* hunter */
535 else if(c=='I' || c=='i') glColor3ub(0xdb,0x70,0xdb); /* indigo */
536 else if(c=='J' || c=='j') glColor3ub(0x80,0x80,0x00); /* olive */
537 else if(c=='K' || c=='k' || c=='0') glColor3ub(0x00,0x00,0x00); /* black */
538 else if(c=='L' || c=='l') glColor3ub(0x32,0xcd,0x32); /* lime */
539 else if(c=='M' || c=='m') glColor3ub(0xff,0x00,0xff); /* magenta */
540 else if(c=='N' || c=='n') glColor3ub(0x00,0x00,0x80); /* navy */
541 else if(c=='O' || c=='o' || c=='3') glColor3ub(0xff,0xaf,0x00); /* orange */
542 else if(c=='P' || c=='p') glColor3ub(0x80,0x00,0x80); /* purple */
543 else if(c=='Q' || c=='q') glColor3ub(0xd9,0xd9,0xf3); /* quartz */
544 else if(c=='R' || c=='r' || c=='2') glColor3ub(0xff,0x00,0x00); /* red */
545 else if(c=='S' || c=='s') glColor3ub(0x8e,0xdb,0x23); /* sienna */
546 else if(c=='T' || c=='t') glColor3ub(0x00,0x80,0x80); /* teal */
547 else if(c=='U' || c=='u') glColor3ub(0x20,0x00,0x20); /* ultraviolet */
548 else if(c=='V' || c=='v' || c=='7') glColor3ub(0xee,0x82,0xee); /* violet */
549 else if(c=='W' || c=='w' || c=='9') glColor3ub(0xff,0xff,0xff); /* white */
550 else if(c=='X' || c=='x') glColor3ub(intrand(0xff),intrand(0xff),intrand(0xff)); /* random */
551 else if(c=='Y' || c=='y' || c=='4') glColor3ub(0xff,0xff,0x00); /* yellow */
552 else if(c=='Z' || c=='z') glColor3ub(intrand(2)*0xff,intrand(2)*0xff,intrand(2)*0xff); /* random */
553 else if(c=='1') glColor3ub(0x40,0x40,0x20); /* brown */
554 else if(c=='-') glColor3ub(0xc0,0xc0,0xc0); /* silver */
555 else if(c=='+') glColor3ub(0xff,0xd7,0x20); /* gold */
556 else glColor3ub(0x00,0x00,0x00); /* black */
557 #endif
558 return; }
559
560
561
562 /* gl2FindRotate */
gl2FindRotate(float * vect1,float * vect2,float * axis)563 float gl2FindRotate(float *vect1,float *vect2,float *axis) {
564 float angle,dot;
565
566 axis[0]=vect1[1]*vect2[2]-vect1[2]*vect2[1];
567 axis[1]=vect1[2]*vect2[0]-vect1[0]*vect2[2];
568 axis[2]=vect1[0]*vect2[1]-vect1[1]*vect2[0];
569 dot=vect1[0]*vect2[0]+vect1[1]*vect2[1]+vect1[2]*vect2[2];
570 angle=acos(dot)*180/PI;
571 if(angle!=0 && angle!=180) return angle;
572 axis[0]=0;
573 axis[1]=vect1[2];
574 axis[2]=-vect1[1];
575 dot=axis[1]*axis[1]+axis[2]*axis[2];
576 if(dot>0) return angle;
577 axis[0]=-vect1[2];
578 axis[1]=0;
579 axis[2]=vect1[0];
580 return angle; }
581
582
583 /* gl2FindRotateD */
gl2FindRotateD(double * vect1,double * vect2,double * axis)584 double gl2FindRotateD(double *vect1,double *vect2,double *axis) {
585 double angle,dot;
586
587 axis[0]=vect1[1]*vect2[2]-vect1[2]*vect2[1];
588 axis[1]=vect1[2]*vect2[0]-vect1[0]*vect2[2];
589 axis[2]=vect1[0]*vect2[1]-vect1[1]*vect2[0];
590 dot=vect1[0]*vect2[0]+vect1[1]*vect2[1]+vect1[2]*vect2[2];
591 angle=acos(dot)*180/PI;
592 if(angle!=0 && angle!=180) return angle;
593 axis[0]=0;
594 axis[1]=vect1[2];
595 axis[2]=-vect1[1];
596 dot=axis[1]*axis[1]+axis[2]*axis[2];
597 if(dot>0) return angle;
598 axis[0]=-vect1[2];
599 axis[1]=0;
600 axis[2]=vect1[0];
601 return angle; }
602
603
604 /* gl2DrawBox */
gl2DrawBox(float * pt1,float * pt2,int dim)605 void gl2DrawBox(float *pt1,float *pt2,int dim) {
606 #ifdef __gl_h_
607 if(dim==1) {
608 glBegin(GL_LINES);
609 glVertex3f(pt1[0],pt1[1],pt1[2]);
610 glVertex3f(pt2[0],pt1[1],pt1[2]);
611 glEnd(); }
612 else if(dim==2) {
613 glBegin(GL_LINE_LOOP);
614 glVertex3f(pt1[0],pt1[1],pt1[2]);
615 glVertex3f(pt2[0],pt1[1],pt1[2]);
616 glVertex3f(pt2[0],pt2[1],pt1[2]);
617 glVertex3f(pt1[0],pt2[1],pt1[2]);
618 glEnd(); }
619 else {
620 glBegin(GL_LINE_STRIP);
621 glVertex3f(pt1[0],pt1[1],pt1[2]);
622 glVertex3f(pt1[0],pt1[1],pt2[2]);
623 glVertex3f(pt1[0],pt2[1],pt2[2]);
624 glVertex3f(pt1[0],pt2[1],pt1[2]);
625 glVertex3f(pt1[0],pt1[1],pt1[2]);
626 glVertex3f(pt2[0],pt1[1],pt1[2]);
627 glVertex3f(pt2[0],pt2[1],pt1[2]);
628 glVertex3f(pt2[0],pt2[1],pt2[2]);
629 glVertex3f(pt2[0],pt1[1],pt2[2]);
630 glVertex3f(pt2[0],pt1[1],pt1[2]);
631 glEnd();
632 glBegin(GL_LINES);
633 glVertex3f(pt1[0],pt1[1],pt2[2]);glVertex3f(pt2[0],pt1[1],pt2[2]);
634 glVertex3f(pt1[0],pt2[1],pt2[2]);glVertex3f(pt2[0],pt2[1],pt2[2]);
635 glVertex3f(pt1[0],pt2[1],pt1[2]);glVertex3f(pt2[0],pt2[1],pt1[2]);
636 glEnd(); }
637 #endif
638 return; }
639
640
641 /* gl2DrawBoxD */
gl2DrawBoxD(double * pt1,double * pt2,int dim)642 void gl2DrawBoxD(double *pt1,double *pt2,int dim) {
643 #ifdef __gl_h_
644 if(dim==1) {
645 glBegin(GL_LINES);
646 glVertex3d(pt1[0],pt1[1],pt1[2]);
647 glVertex3d(pt2[0],pt1[1],pt1[2]);
648 glEnd(); }
649 else if(dim==2) {
650 glBegin(GL_LINE_LOOP);
651 glVertex3d(pt1[0],pt1[1],pt1[2]);
652 glVertex3d(pt2[0],pt1[1],pt1[2]);
653 glVertex3d(pt2[0],pt2[1],pt1[2]);
654 glVertex3d(pt1[0],pt2[1],pt1[2]);
655 glEnd(); }
656 else {
657 glBegin(GL_LINE_STRIP);
658 glVertex3d(pt1[0],pt1[1],pt1[2]);
659 glVertex3d(pt1[0],pt1[1],pt2[2]);
660 glVertex3d(pt1[0],pt2[1],pt2[2]);
661 glVertex3d(pt1[0],pt2[1],pt1[2]);
662 glVertex3d(pt1[0],pt1[1],pt1[2]);
663 glVertex3d(pt2[0],pt1[1],pt1[2]);
664 glVertex3d(pt2[0],pt2[1],pt1[2]);
665 glVertex3d(pt2[0],pt2[1],pt2[2]);
666 glVertex3d(pt2[0],pt1[1],pt2[2]);
667 glVertex3d(pt2[0],pt1[1],pt1[2]);
668 glEnd();
669 glBegin(GL_LINES);
670 glVertex3d(pt1[0],pt1[1],pt2[2]);glVertex3d(pt2[0],pt1[1],pt2[2]);
671 glVertex3d(pt1[0],pt2[1],pt2[2]);glVertex3d(pt2[0],pt2[1],pt2[2]);
672 glVertex3d(pt1[0],pt2[1],pt1[2]);glVertex3d(pt2[0],pt2[1],pt1[2]);
673 glEnd(); }
674 #endif
675 return; }
676
677
678 /* gl2DrawBoxFaceD */
gl2DrawBoxFaceD(double * pt1,double * pt2,int dim)679 void gl2DrawBoxFaceD(double *pt1,double *pt2,int dim) {
680 #ifdef __gl_h_
681 if(dim==2) {
682 glBegin(GL_POLYGON);
683 glVertex3d(pt1[0],pt1[1],pt1[2]);
684 glVertex3d(pt1[0],pt2[1],pt1[2]);
685 glVertex3d(pt2[0],pt2[1],pt1[2]);
686 glVertex3d(pt2[0],pt1[1],pt1[2]);
687 glEnd(); }
688 else if(dim==3) {
689 glBegin(GL_POLYGON);
690 glVertex3d(pt1[0],pt1[1],pt1[2]);
691 glVertex3d(pt1[0],pt2[1],pt1[2]);
692 glVertex3d(pt2[0],pt2[1],pt1[2]);
693 glVertex3d(pt2[0],pt1[1],pt1[2]);
694 glEnd();
695 glBegin(GL_POLYGON);
696 glVertex3d(pt1[0],pt1[1],pt2[2]);
697 glVertex3d(pt1[0],pt2[1],pt2[2]);
698 glVertex3d(pt2[0],pt2[1],pt2[2]);
699 glVertex3d(pt2[0],pt1[1],pt2[2]);
700 glEnd();
701 glBegin(GL_POLYGON);
702 glVertex3d(pt1[0],pt1[1],pt1[2]);
703 glVertex3d(pt1[0],pt1[1],pt2[2]);
704 glVertex3d(pt2[0],pt1[1],pt2[2]);
705 glVertex3d(pt2[0],pt1[1],pt1[2]);
706 glEnd();
707 glBegin(GL_POLYGON);
708 glVertex3d(pt1[0],pt2[1],pt1[2]);
709 glVertex3d(pt1[0],pt2[1],pt2[2]);
710 glVertex3d(pt2[0],pt2[1],pt2[2]);
711 glVertex3d(pt2[0],pt2[1],pt1[2]);
712 glEnd();
713 glBegin(GL_POLYGON);
714 glVertex3d(pt1[0],pt1[1],pt1[2]);
715 glVertex3d(pt1[0],pt1[1],pt2[2]);
716 glVertex3d(pt1[0],pt2[1],pt2[2]);
717 glVertex3d(pt1[0],pt2[1],pt1[2]);
718 glEnd();
719 glBegin(GL_POLYGON);
720 glVertex3d(pt2[0],pt1[1],pt1[2]);
721 glVertex3d(pt2[0],pt1[1],pt2[2]);
722 glVertex3d(pt2[0],pt2[1],pt2[2]);
723 glVertex3d(pt2[0],pt2[1],pt1[2]);
724 glEnd(); }
725 #endif
726 return; }
727
728
729 /* gl2DrawGrid */
gl2DrawGrid(float * pt1,float * pt2,int * n,int dim)730 void gl2DrawGrid(float *pt1,float *pt2,int *n,int dim) {
731 #ifdef __gl_h_
732 float delta1,delta2;
733 int i,j;
734
735 if(dim==1) {
736 glBegin(GL_POINTS);
737 delta1=(pt2[0]-pt1[0])/n[0];
738 for(i=0;i<=n[0];i++)
739 glVertex3f(pt1[0]+i*delta1,pt1[1],pt1[2]);
740 glEnd(); }
741 else if(dim==2) {
742 glBegin(GL_LINES);
743 delta1=(pt2[1]-pt1[1])/n[1];
744 for(i=0;i<=n[1];i++) {
745 glVertex3f(pt1[0],pt1[1]+i*delta1,pt1[2]);
746 glVertex3f(pt2[0],pt1[1]+i*delta1,pt1[2]); }
747 delta1=(pt2[0]-pt1[0])/n[0];
748 for(i=0;i<=n[0];i++) {
749 glVertex3f(pt1[0]+i*delta1,pt1[1],pt1[2]);
750 glVertex3f(pt1[0]+i*delta1,pt2[1],pt1[2]); }
751 glEnd(); }
752 else if(dim==3) {
753 glBegin(GL_LINES);
754 delta1=(pt2[1]-pt1[1])/n[1];
755 delta2=(pt2[2]-pt1[2])/n[2];
756 for(i=0;i<=n[1];i++)
757 for(j=0;j<=n[2];j++) {
758 glVertex3f(pt1[0],pt1[1]+i*delta1,pt1[2]+j*delta2);
759 glVertex3f(pt2[0],pt1[1]+i*delta1,pt1[2]+j*delta2); }
760 delta1=(pt2[0]-pt1[0])/n[0];
761 delta2=(pt2[2]-pt1[2])/n[2];
762 for(i=0;i<=n[0];i++)
763 for(j=0;j<=n[2];j++) {
764 glVertex3f(pt1[0]+i*delta1,pt1[1],pt1[2]+j*delta2);
765 glVertex3f(pt1[0]+i*delta1,pt2[1],pt1[2]+j*delta2); }
766 delta1=(pt2[0]-pt1[0])/n[0];
767 delta2=(pt2[1]-pt1[1])/n[1];
768 for(i=0;i<=n[0];i++)
769 for(j=0;j<=n[1];j++) {
770 glVertex3f(pt1[0]+i*delta1,pt1[1]+j*delta2,pt1[2]);
771 glVertex3f(pt1[0]+i*delta1,pt1[1]+j*delta2,pt2[2]); }
772 glEnd(); }
773 #endif
774 return; }
775
776
777
778 /* gl2DrawGridD */
gl2DrawGridD(double * pt1,double * pt2,int * n,int dim)779 void gl2DrawGridD(double *pt1,double *pt2,int *n,int dim) {
780 #ifdef __gl_h_
781 double delta1,delta2;
782 int i,j;
783
784 if(dim==1) {
785 glBegin(GL_POINTS);
786 delta1=(pt2[0]-pt1[0])/n[0];
787 for(i=0;i<=n[0];i++)
788 glVertex3d(pt1[0]+i*delta1,pt1[1],pt1[2]);
789 glEnd(); }
790 else if(dim==2) {
791 glBegin(GL_LINES);
792 delta1=(pt2[1]-pt1[1])/n[1];
793 for(i=0;i<=n[1];i++) {
794 glVertex3d(pt1[0],pt1[1]+i*delta1,pt1[2]);
795 glVertex3d(pt2[0],pt1[1]+i*delta1,pt1[2]); }
796 delta1=(pt2[0]-pt1[0])/n[0];
797 for(i=0;i<=n[0];i++) {
798 glVertex3d(pt1[0]+i*delta1,pt1[1],pt1[2]);
799 glVertex3d(pt1[0]+i*delta1,pt2[1],pt1[2]); }
800 glEnd(); }
801 else if(dim==3) {
802 glBegin(GL_LINES);
803 delta1=(pt2[1]-pt1[1])/n[1];
804 delta2=(pt2[2]-pt1[2])/n[2];
805 for(i=0;i<=n[1];i++)
806 for(j=0;j<=n[2];j++) {
807 glVertex3d(pt1[0],pt1[1]+i*delta1,pt1[2]+j*delta2);
808 glVertex3d(pt2[0],pt1[1]+i*delta1,pt1[2]+j*delta2); }
809 delta1=(pt2[0]-pt1[0])/n[0];
810 delta2=(pt2[2]-pt1[2])/n[2];
811 for(i=0;i<=n[0];i++)
812 for(j=0;j<=n[2];j++) {
813 glVertex3d(pt1[0]+i*delta1,pt1[1],pt1[2]+j*delta2);
814 glVertex3d(pt1[0]+i*delta1,pt2[1],pt1[2]+j*delta2); }
815 delta1=(pt2[0]-pt1[0])/n[0];
816 delta2=(pt2[1]-pt1[1])/n[1];
817 for(i=0;i<=n[0];i++)
818 for(j=0;j<=n[1];j++) {
819 glVertex3d(pt1[0]+i*delta1,pt1[1]+j*delta2,pt1[2]);
820 glVertex3d(pt1[0]+i*delta1,pt1[1]+j*delta2,pt2[2]); }
821 glEnd(); }
822 #endif
823 return; }
824
825
826
827 /* gl2DrawCircle */
gl2DrawCircle(float * cent,float radius,int slices,char style,int dim)828 void gl2DrawCircle(float *cent,float radius,int slices,char style,int dim) {
829 #ifdef __gl_h_
830 int i;
831 float theta,dtheta;
832
833 if(style=='g') {
834 gl2DrawCircle(cent,radius,slices,'f',dim);
835 gl2DrawCircle(cent,radius,slices,'e',dim);
836 return; }
837
838 dtheta=2*PI/slices;
839 if(style=='f') {
840 glBegin(GL_TRIANGLE_FAN);
841 if(dim==2) glVertex2fv(cent);
842 else {
843 glNormal3f(0,0,1);
844 glVertex3fv(cent); }}
845 else if(style=='e') glBegin(GL_LINE_LOOP);
846 else glBegin(GL_POINTS);
847 if(dim==2)
848 for(i=0;i<slices;i++) {
849 theta=i*dtheta;
850 glVertex2f(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta)); }
851 else
852 for(i=0;i<slices;i++) {
853 theta=i*dtheta;
854 glVertex3f(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta),cent[2]); }
855 if(style=='e' || style=='f') {
856 theta=i*dtheta;
857 if(dim==2) glVertex2f(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta));
858 else glVertex3f(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta),cent[2]); }
859 glEnd();
860
861 #endif
862 return; }
863
864
865
866 /* gl2DrawCircleD */
gl2DrawCircleD(double * cent,double radius,int slices,char style,int dim)867 void gl2DrawCircleD(double *cent,double radius,int slices,char style,int dim) {
868 #ifdef __gl_h_
869 int i;
870 double theta,dtheta;
871
872 if(style=='g') {
873 gl2DrawCircleD(cent,radius,slices,'f',dim);
874 gl2DrawCircleD(cent,radius,slices,'e',dim);
875 return; }
876
877 dtheta=2*PI/slices;
878 if(style=='f') {
879 glBegin(GL_TRIANGLE_FAN);
880 if(dim==2) glVertex2dv(cent);
881 else {
882 glNormal3d(0,0,1);
883 glVertex3dv(cent); }}
884 else if(style=='e') glBegin(GL_LINE_LOOP);
885 else glBegin(GL_POINTS);
886 if(dim==2)
887 for(i=0;i<slices;i++) {
888 theta=i*dtheta;
889 glVertex2d(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta)); }
890 else
891 for(i=0;i<slices;i++) {
892 theta=i*dtheta;
893 glVertex3d(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta),cent[2]); }
894 if(style=='e' || style=='f') {
895 theta=i*dtheta;
896 if(dim==2) glVertex2d(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta));
897 else glVertex3d(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta),cent[2]); }
898 glEnd();
899 #endif
900 return; }
901
902
903
904 /* gl2DrawArc */
gl2DrawArc(float * cent,float radius,float theta1,float theta2,int slices,char style,int dim)905 void gl2DrawArc(float *cent,float radius,float theta1,float theta2,int slices,char style,int dim) {
906 #ifdef __gl_h_
907 int i,imax;
908 float theta,dtheta;
909
910 dtheta=2.0*PI/slices;
911 imax=(int)((theta2-theta1)/dtheta+0.5);
912 dtheta=(theta2-theta1)/(float)imax;
913 if(style=='f' || style=='g') {
914 glBegin(GL_TRIANGLE_FAN);
915 if(dim==2) glVertex2fv(cent);
916 else {
917 glNormal3f(0,0,1);
918 glVertex3fv(cent); }}
919 else if(style=='e') glBegin(GL_LINE_STRIP);
920 else glBegin(GL_POINTS);
921 if(dim==2)
922 for(i=0;i<=imax;i++) {
923 theta=theta1+i*dtheta;
924 glVertex2f(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta)); }
925 else
926 for(i=0;i<=imax;i++) {
927 theta=theta1+i*dtheta;
928 glVertex3f(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta),cent[2]); }
929 glEnd();
930 #endif
931 return; }
932
933
934
935 /* gl2DrawArcD */
gl2DrawArcD(double * cent,double radius,double theta1,double theta2,int slices,char style,int dim)936 void gl2DrawArcD(double *cent,double radius,double theta1,double theta2,int slices,char style,int dim) {
937 #ifdef __gl_h_
938 int i,imax;
939 double theta,dtheta;
940
941 dtheta=2.0*PI/slices;
942 imax=(int)((theta2-theta1)/dtheta+0.5);
943 dtheta=(theta2-theta1)/(double)imax;
944 if(style=='f' || style=='g') {
945 glBegin(GL_TRIANGLE_FAN);
946 if(dim==2) glVertex2dv(cent);
947 else {
948 glNormal3d(0,0,1);
949 glVertex3dv(cent); }}
950 else if(style=='e') glBegin(GL_LINE_STRIP);
951 else glBegin(GL_POINTS);
952 if(dim==2)
953 for(i=0;i<=imax;i++) {
954 theta=theta1+i*dtheta;
955 glVertex2d(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta)); }
956 else
957 for(i=0;i<=imax;i++) {
958 theta=theta1+i*dtheta;
959 glVertex3d(cent[0]+radius*cos(theta),cent[1]+radius*sin(theta),cent[2]); }
960 glEnd();
961 #endif
962 return; }
963
964
965
966 /* gl2DrawHemisphere */
gl2DrawHemisphere(float radius,int slices,int stacks,int frontin,int normals)967 void gl2DrawHemisphere(float radius,int slices,int stacks,int frontin,int normals) {
968 #ifdef __gl_h_
969 int ilong,ilat,ilong1,ilong2,dilong;
970 float dtheta,dphi,r1,r2,z1,z2,cosphi,sinphi,normfact;
971
972 if(frontin) {
973 ilong1=0;
974 ilong2=slices+1;
975 dilong=1; }
976 else {
977 ilong1=slices;
978 ilong2=-1;
979 dilong=-1; }
980
981 dtheta=PI/2.0/stacks;
982 dphi=2.0*PI/slices;
983 r2=radius;
984 z2=0;
985 normfact=1.0/radius*(frontin?-1.0:1.0);
986
987 for(ilat=1;ilat<stacks;ilat++) {
988 r1=r2; // r1 is radius of bottom edge (starts on xy plane)
989 z1=z2; // z1 is height of bottom edge
990 r2=radius*cos(ilat*dtheta); // r2 is radius of top edge
991 z2=radius*sin(ilat*dtheta); // z2 is height of top edge
992 glBegin(GL_QUAD_STRIP);
993 if(!normals)
994 for(ilong=ilong1;ilong!=ilong2;ilong+=dilong) {
995 cosphi=cos(ilong*dphi);
996 sinphi=sin(ilong*dphi);
997 glVertex3f(r1*cosphi,r1*sinphi,z1);
998 glVertex3f(r2*cosphi,r2*sinphi,z2); }
999 else
1000 for(ilong=ilong1;ilong!=ilong2;ilong+=dilong) {
1001 cosphi=cos(ilong*dphi);
1002 sinphi=sin(ilong*dphi);
1003 glNormal3f(r1*normfact*cosphi,r1*normfact*sinphi,z1*normfact);
1004 glVertex3f(r1*cosphi,r1*sinphi,z1);
1005 glNormal3f(r2*normfact*cosphi,r2*normfact*sinphi,z2*normfact);
1006 glVertex3f(r2*cosphi,r2*sinphi,z2); }
1007 glEnd(); }
1008
1009 r1=r2;
1010 z1=z2;
1011 glBegin(GL_TRIANGLE_FAN);
1012 if(normals) {
1013 if(frontin)
1014 glNormal3f(0,0,-1);
1015 else
1016 glNormal3f(0,0,1); }
1017 glVertex3f(0,0,radius);
1018 if(!normals)
1019 for(ilong=ilong2;ilong!=ilong1;ilong-=dilong) {
1020 glVertex3f(r1*cos(ilong*dphi),r1*sin(ilong*dphi),z1); }
1021 else {
1022 for(ilong=ilong2;ilong!=ilong1;ilong-=dilong) {
1023 cosphi=cos(ilong*dphi);
1024 sinphi=sin(ilong*dphi);
1025 glNormal3f(r1*normfact*cosphi,r1*normfact*sinphi,z1*normfact);
1026 glVertex3f(r1*cosphi,r1*sinphi,z1); }}
1027 glEnd();
1028
1029 #endif
1030 return; }
1031
1032
1033
1034 /* gl2DrawCylinder */
gl2DrawCylinder(float baseRadius,float topRadius,float height,int slices,int stacks,int frontin,int normals)1035 void gl2DrawCylinder(float baseRadius,float topRadius,float height,int slices,int stacks,int frontin,int normals) {
1036 #ifdef __gl_h_
1037 int ilen,irad,irad1,irad2,dirad;
1038 float dtheta,dlen,z1,z2,r1,r2,costheta,sintheta,normxy,normz;
1039
1040 if(frontin) {irad1=0;irad2=slices+1;dirad=1;}
1041 else {irad1=slices;irad2=-1;dirad=-1;}
1042
1043 dtheta=2.0*PI/slices;
1044 dlen=height/stacks;
1045 z2=0;
1046 r2=baseRadius;
1047 if(baseRadius==topRadius) {
1048 normxy=frontin?-1.0:1.0;
1049 normz=0; }
1050 else {
1051 normxy=(frontin?-1.0:1.0)/sqrt((baseRadius-topRadius)*(baseRadius-topRadius)+height*height);
1052 normz=(baseRadius-topRadius)*normxy;
1053 normxy*=height; }
1054
1055 for(ilen=1;ilen<=stacks;ilen++) {
1056 z1=z2; // z1 is bottom height, starts on xy plane
1057 r1=r2; // r1 is bottom radius
1058 z2=ilen*dlen; // z2 is top height
1059 r2=baseRadius*(1.0-z2/height)+topRadius*z2/height; // r2 is top radius
1060 glBegin(GL_QUAD_STRIP);
1061 if(!normals)
1062 for(irad=irad1;irad!=irad2;irad+=dirad) {
1063 costheta=cos(irad*dtheta);
1064 sintheta=sin(irad*dtheta);
1065 glVertex3f(r1*costheta,r1*sintheta,z1);
1066 glVertex3f(r2*costheta,r2*sintheta,z2); }
1067 else
1068 for(irad=irad1;irad!=irad2;irad+=dirad) {
1069 costheta=cos(irad*dtheta);
1070 sintheta=sin(irad*dtheta);
1071 glNormal3f(costheta*normxy,sintheta*normxy,normz);
1072 glVertex3f(r1*costheta,r1*sintheta,z1);
1073 glVertex3f(r2*costheta,r2*sintheta,z2); }
1074 glEnd(); }
1075 #endif
1076 return; }
1077
1078
1079
1080 /* gl2DrawSphere */
gl2DrawSphere(float radius,int slices,int stacks,int frontin,int normals)1081 void gl2DrawSphere(float radius,int slices,int stacks,int frontin,int normals) {
1082 #ifdef __gl_h_
1083 glMatrixMode(GL_MODELVIEW);
1084 glPushMatrix();
1085 gl2DrawHemisphere(radius,slices,stacks/2,frontin,normals);
1086 glRotatef(180,1,0,0);
1087 gl2DrawHemisphere(radius,slices,stacks/2,frontin,normals);
1088 glPopMatrix();
1089 #endif
1090 return; }
1091
1092
1093
1094 /* gl2DrawEcoli */
gl2DrawEcoli(float radius,float length,int slices,int stacks,int frontin,int normals)1095 void gl2DrawEcoli(float radius,float length,int slices,int stacks,int frontin,int normals) {
1096 #ifdef __gl_h_
1097 int endstacks;
1098
1099 endstacks=(int)(radius*PI/2.0/length*stacks);
1100 length-=2*radius;
1101 if(length<0) length=0;
1102 glMatrixMode(GL_MODELVIEW);
1103 glPushMatrix();
1104 glTranslatef(0,0,length/2);
1105 gl2DrawHemisphere(radius,slices,endstacks,frontin,normals);
1106 glTranslatef(0,0,-length);
1107 if(length) gl2DrawCylinder(radius,radius,length,slices,stacks-2*endstacks,frontin,normals);
1108 glRotatef(180,1,0,0);
1109 gl2DrawHemisphere(radius,slices,endstacks,frontin,normals);
1110 glPopMatrix();
1111 #endif
1112 return; }
1113
1114
1115
1116 /* gl2DrawTextD */
gl2DrawTextD(double x,double y,double * color,void * font,char * string,int align)1117 void gl2DrawTextD(double x,double y,double *color,void *font,char *string,int align) {
1118 #ifdef __gl_h_
1119 int i,width,length;
1120
1121 glMatrixMode(GL_PROJECTION);
1122 glPushMatrix();
1123 glLoadIdentity();
1124 gluOrtho2D(0,100,0,100); // defines clipping region as 100 x 100
1125 glMatrixMode(GL_MODELVIEW);
1126 glPushMatrix();
1127 glLoadIdentity();
1128 glColor3dv((GLdouble*)color);
1129 glRasterPos2i((GLint)x,(GLint)y);
1130 length=strlen(string);
1131 if(align>=0) {
1132 width=glutBitmapLength(font,(const unsigned char*)string);
1133 glBitmap(0,0,0,0,align?-width:-width/2,0,NULL); }
1134 for(i=0;i<length;i++)
1135 glutBitmapCharacter(font,string[i]);
1136 glMatrixMode(GL_MODELVIEW);
1137 glPopMatrix();
1138 glMatrixMode(GL_PROJECTION);
1139 glPopMatrix();
1140 #endif
1141 return; }
1142
1143
1144
1145 /* gl2PlotData */
1146 // style is 3 characters per data set: style,width,color
gl2PlotData(float * xdata,float * ydata,int nx,int nycol,char * style)1147 void gl2PlotData(float *xdata,float *ydata,int nx,int nycol,char *style) {
1148 #ifdef __gl_h_
1149 int i,j;
1150
1151 for(j=0;j<nycol;j++) {
1152 if(style[3*j]==' '); // not drawn
1153 else if(style[3*j]=='-') { // solid line
1154 glLineWidth(style[3*j+1]-'0');
1155 gl2SetColor(style[3*j+2]);
1156 glBegin(GL_LINE_STRIP);
1157 for(i=0;i<nx;i++)
1158 glVertex3f(xdata[i],ydata[i*nycol+j],0);
1159 glEnd(); }
1160 else if(style[3*j]=='.') { // dots
1161 glPointSize(style[3*j+1]-'0');
1162 gl2SetColor(style[3*j+2]);
1163 glBegin(GL_POINTS);
1164 for(i=0;i<nx;i++)
1165 glVertex3f(xdata[i],ydata[i*nycol+j],0);
1166 glEnd(); }
1167 else if(style[3*j]=='h') { // histogram **** NEEDS WORK ****
1168 glLineWidth(style[3*j+1]-'0');
1169 gl2SetColor(style[3*j+2]);
1170 glBegin(GL_LINE_STRIP);
1171 glVertex3f(xdata[0],0,0);
1172 for(i=0;i<nx-1;i++) {
1173 glVertex3f(xdata[i],ydata[i*nycol+j],0);
1174 glVertex3f(xdata[i+1],ydata[i*nycol+j],0); }
1175 if(nx>1) {
1176 glVertex3f(xdata[i],ydata[i*nycol+j],0);
1177 glVertex3f(2*xdata[i]-xdata[i-1],ydata[i*nycol+j],0);
1178 glVertex3f(2*xdata[i]-xdata[i-1],0,0); }
1179 glEnd(); }}
1180 #endif
1181 return; }
1182
1183
1184
1185 /* gl2PlotPts */
gl2PlotPts(float ** data,int * ser,int nser,int npts,float ** color,float * size,char style)1186 void gl2PlotPts(float **data,int *ser,int nser,int npts,float **color,float *size,char style) {
1187 #ifdef __gl_h_
1188 int i,j;
1189
1190 if(style==' ');
1191 else if(style=='.') {
1192 for(j=0;j<nser;j++) {
1193 if(size[j]>0) {
1194 glPointSize(size[j]);
1195 glColor3f(color[j][0],color[j][1],color[j][2]);
1196 glBegin(GL_POINTS);
1197 for(i=0;i<npts;i++)
1198 if(ser[i]==j) glVertex3f(data[i][0],data[i][1],data[i][2]);
1199 glEnd(); }}}
1200 else if(style=='-') {
1201 for(j=0;j<nser;j++) {
1202 if(size[j]>0) {
1203 glLineWidth(size[j]);
1204 glColor3f(color[j][0],color[j][1],color[j][2]);
1205 glBegin(GL_LINE_STRIP);
1206 for(i=0;i<npts;i++)
1207 if(ser[i]==j) glVertex3f(data[i][0],data[i][1],data[i][2]);
1208 glEnd(); }}}
1209 else if(style=='s') {
1210 glMatrixMode(GL_MODELVIEW);
1211 for(j=0;j<nser;j++) {
1212 if(size[j]>0) {
1213 glColor3f(color[j][0],color[j][1],color[j][2]);
1214 for(i=0;i<npts;i++)
1215 if(ser[i]==j) {
1216 glPushMatrix();
1217 glTranslatef(data[i][0],data[i][1],data[i][2]);
1218 glutSolidSphere(size[j],15,15);
1219 glPopMatrix(); }}}}
1220 #endif
1221 return; }
1222
1223
1224
1225 /* gl2PlotPtsD */
gl2PlotPtsD(double ** data,int * ser,int nser,int npts,double ** color,double * size,char style)1226 void gl2PlotPtsD(double **data,int *ser,int nser,int npts,double **color,double *size,char style) {
1227 #ifdef __gl_h_
1228 int i,j;
1229
1230 if(style==' ');
1231 else if(style=='.') {
1232 for(j=0;j<nser;j++) {
1233 if(size[j]>0) {
1234 glPointSize(size[j]);
1235 glColor3d(color[j][0],color[j][1],color[j][2]);
1236 glBegin(GL_POINTS);
1237 for(i=0;i<npts;i++)
1238 if(ser[i]==j) glVertex3d(data[i][0],data[i][1],data[i][2]);
1239 glEnd(); }}}
1240 else if(style=='-') {
1241 for(j=0;j<nser;j++) {
1242 if(size[j]>0) {
1243 glLineWidth(size[j]);
1244 glColor3d(color[j][0],color[j][1],color[j][2]);
1245 glBegin(GL_LINE_STRIP);
1246 for(i=0;i<npts;i++)
1247 if(ser[i]==j) glVertex3d(data[i][0],data[i][1],data[i][2]);
1248 glEnd(); }}}
1249 else if(style=='s') {
1250 glMatrixMode(GL_MODELVIEW);
1251 for(j=0;j<nser;j++) {
1252 if(size[j]>0) {
1253 glColor3d(color[j][0],color[j][1],color[j][2]);
1254 for(i=0;i<npts;i++)
1255 if(ser[i]==j) {
1256 glPushMatrix();
1257 glTranslated(data[i][0],data[i][1],data[i][2]);
1258 glutSolidSphere(size[j],15,15);
1259 glPopMatrix(); }}}}
1260 #endif
1261 return; }
1262
1263
1264
1265 /* gl2PlotSurf */
gl2PlotSurf(float * xdata,float * ydata,float ** zdata,int nx,int ny,int nz,char * style)1266 void gl2PlotSurf(float *xdata,float *ydata,float **zdata,int nx,int ny,int nz,char *style) {
1267 #ifdef __gl_h_
1268 int ix,iy,iz,ic;
1269 float dxlo,dxhi,dylo,dyhi;
1270 float col1[64][4],col2[4];
1271
1272 if(style[0]=='s') {
1273 if(nz>64) nz=64;
1274 for(iz=0;iz<nz;iz++) {
1275 gl2SetColor(style[iz+1]);
1276 glGetFloatv(GL_CURRENT_COLOR,col1[iz]); }
1277 for(iy=0;iy<ny;iy++) {
1278 if(ny>1) {
1279 if(iy==0) dylo=dyhi=0.5*(ydata[1]-ydata[0]);
1280 else if(iy==ny-1) dylo=dyhi=0.5*(ydata[ny-1]-ydata[ny-2]);
1281 else {
1282 dylo=0.5*(ydata[iy]-ydata[iy-1]);
1283 dyhi=0.5*(ydata[iy+1]-ydata[iy]); }}
1284 else dylo=dyhi=0.5*(ClipTop-ClipBot);
1285 for(ix=0;ix<nx;ix++) {
1286 if(nx>1) {
1287 if(ix==0) dxlo=dxhi=0.5*(xdata[1]-xdata[0]);
1288 else if(ix==nx-1) dxlo=dxhi=0.5*(xdata[nx-1]-xdata[nx-2]);
1289 else {
1290 dxlo=0.5*(xdata[ix]-xdata[ix-1]);
1291 dxhi=0.5*(xdata[ix+1]-xdata[ix]); }}
1292 else dxlo=dxhi=0.5*(ClipRight-ClipLeft);
1293 for(ic=0;ic<4;ic++) col2[ic]=0;
1294 for(iz=0;iz<nz;iz++)
1295 for(ic=0;ic<4;ic++) col2[ic]+=zdata[iy*nx+ix][iz]*col1[iz][ic];
1296 glColor4fv(col2);
1297 glRectf(xdata[ix]-dxlo,ydata[iy]-dylo,xdata[ix]+dxhi,ydata[iy]+dyhi); }}}
1298
1299 #endif
1300 return; }
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314