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