1 /*
2  * GL2PS, an OpenGL to PostScript Printing Library
3  * Copyright (C) 1999-2009 Christophe Geuzaine <geuz@geuz.org>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of either:
7  *
8  * a) the GNU Library General Public License as published by the Free
9  * Software Foundation, either version 2 of the License, or (at your
10  * option) any later version; or
11  *
12  * b) the GL2PS License as published by Christophe Geuzaine, either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either
18  * the GNU Library General Public License or the GL2PS License for
19  * more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library in the file named "COPYING.LGPL";
23  * if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
24  * Cambridge, MA 02139, USA.
25  *
26  * You should have received a copy of the GL2PS License with this
27  * library in the file named "COPYING.GL2PS"; if not, I will be glad
28  * to provide one.
29  *
30  * For the latest info about gl2ps and a full list of contributors,
31  * see http://www.geuz.org/gl2ps/.
32  *
33  * Please report all bugs and problems to <gl2ps@geuz.org>.
34  */
35 
36 /*
37   To compile on Linux:
38   gcc gl2psTest.c gl2ps.c -lglut -lGL -lGLU -lX11 -lm
39 
40   To compile on MacOSX:
41   gcc gl2psTest.c gl2ps.c -framework OpenGL -framework GLUT -framework Cocoa
42 
43   (To enable file compression you must add "-DHAVE_ZLIB -lz" to the
44   commands above.  To enable embedded bitmaps in SVG files you must
45   add "-DHAVE_LIBPNG -DHAVE_ZLIB -lpng -lz".)
46 */
47 
48 #ifdef _MSC_VER /* MSVC Compiler */
49 #pragma comment(linker, "/entry:\"mainCRTStartup\"")
50 #endif
51 
52 #include "gl2ps.h"
53 
54 #include <string.h>
55 #ifdef __APPLE__
56 #  include <GLUT/glut.h>
57 #else
58 #  include <GL/glut.h>
59 #endif
60 
61 static float rotation = -58.;
62 static GLsizei window_w = 0;
63 static GLsizei window_h = 0;
64 static GLboolean display_multi = GL_TRUE;
65 static GLboolean blend = GL_FALSE;
66 static GLboolean teapot = GL_FALSE;
67 static char *pixmap[] = {
68   "****************************************************************",
69   "*..............................................................*",
70   "*..................++++++++++++++++++++++++++..................*",
71   "*.............+++++++++++++++++++++++++++++++++++++............*",
72   "*.......++++++++++++aaaaaaaaaaaaaaaaaaaaaaaa++++++++++++.......*",
73   "*.......++++++aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa++++++.......*",
74   "*.......++aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa++.......*",
75   "*.......++aaaa++++aa+aaaaaaaa++++aaa++++++aaa+++++aaaa++.......*",
76   "*.......++aaa+aaaa+a+aaaaaaa+aaaa+aa+aaaaa+a+aaaaa+aaa++.......*",
77   "*.......++aa+aaaaaaa+aaaaaaaaaaa+aaa+aaaaa+a+aaaaaaaaa++.......*",
78   "*.......++aa+aaa+++a+aaaaaaaaaa+aaaa++++++aaa+++++aaaa++.......*",
79   "*.......++aa+aaaaa+a+aaaaaaaaa+aaaaa+aaaaaaaaaaaaa+aaa++.......*",
80   "*.......++aaa+aaaa+a+aaaaaaaa+aaaaaa+aaaaaaa+aaaaa+aaa++.......*",
81   "*.......++aaaa+++++a++++++aa++++++aa+aaaaaaaa+++++aaaa++.......*",
82   "*.......++aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa++.......*",
83   "*.......++aaaaaaaaa++++++++++++++++++++++++++aaaaaaaaa++.......*",
84   "*.......++aaa+++++++@@@@@@@@@@@+++++++++++++++++++aaaa++.......*",
85   "*.......++++++@@+@@@+@@@++@@@@@+++++++++++++++++++++++++.......*",
86   "*.......++@@@@@+@@@+@@@+@@@@+@@+++++++++++++++++++++++++.......*",
87   "*.......++@@@@+@@@+@@+++++++@@@+++++++++++++++++++++++++.......*",
88   "*.......++@@@@+++++++@@@@@@++@@++#####################++.......*",
89   "*.......++@+++++@@@@@@@@@@@@@@@++#####################++.......*",
90   "*.......++@+++@@@@@@@@@@@@@@@@@++#####################++.......*",
91   "*.......++@++@@@@@@@+@@+@@@@@@@++#####################++.......*",
92   "*.......++@@@@@+@@@+@@+@@@@@@@@++#####################++.......*",
93   "*.......++@@@@+@@@+@@+@@++++++++++++++++++++++++++++++++.......*",
94   "*.......++@@@@+@+++++++++@++++@+@+@+++++++++++++++++++++.......*",
95   "*.......++@@@@+++@@@@@@@+@++@+++@+@+@+@+++++++++++++++++.......*",
96   "*.......++@++++@@@@@@@@@@+@+++@+@+@+++++++++++++++++++++.......*",
97   "*.......++@+++@@@@@@@@@@+@@@@@@@@@@@@@@+++++++++++++++++.......*",
98   "*.......++@++@@@@@@+@@+@+@@@+++@@@@@@@@+++++++++++++++++.......*",
99   "*.......++@@@@@+@@+@@+@@+@@+++++@@@@@@@+##############++.......*",
100   "*.......++@@@@+@@+@@+@@++@@+@+++@@@@@+@+##############++.......*",
101   "*.......++@@@@+@+++++++@+@@@@+++@@@@++@+##############++.......*",
102   "*.......++@++++++@@@@@@++@@@@+++@@@@++@+##############++.......*",
103   "*.......++@+++@@@@@@@@@@+@@@+++++@@@+@@+##############++.......*",
104   "*.......++@++@@@@@@@@@@@+@+++++++++++@@+##############++.......*",
105   "*.......+++++++++++++++++@+@+++++++++@@+++++++++++++++++.......*",
106   "*.......+++++++++++++++++@+@+@@@@++++@@+@@@@@@@@@@@@@@++.......*",
107   "*.......+++++++++++++++++@@@+@@@@@+@+@@+@@@+@@+@@@@@@@++.......*",
108   "*........++++++++++++++++@@@@+@@@++@++@+@@+@@+@@@+@@@++........*",
109   "*........++++++++++++++++@@@@@@@@+@@+@@+@+@@+@@@+@@@@++........*",
110   "*........+++++++++++++++++@@@@@@+@@+@@+@++++++++++@@@++........*",
111   "*.........++##############+@@@@@@@@@@++++@@@@@@@@++@++.........*",
112   "*.........++###############+@@@@@@@@++++@@@@@@@@@@@@++.........*",
113   "*..........++###############++++++++@@@@@@@+@@+@@@@++..........*",
114   "*..........++##################++@@@@@+@@@+@@+@@+@@++..........*",
115   "*...........++#################++@@@@+@@@+@@+@@+@@++...........*",
116   "*...........++#################++@@@+@@++++++++@@@++...........*",
117   "*............++++++++++++++++++++@@@++++@@@@@@++@++............*",
118   "*.............+++++++++++++++++++@@+++@@@@@@@@@@@+.............*",
119   "*.............+++++++++++++++++++@+++@@@@@@@@@@@++.............*",
120   "*..............++++++++++++++++++@++@@@@+@@@@@@++..............*",
121   "*...............+++++++++++++++++@@@+@@+@@+@@@++...............*",
122   "*................++++++++++++++++@@+@@+@@+@@@++................*",
123   "*.................++###########++@@+++++++@@++.................*",
124   "*..................++##########++@+++@@@@+@++..................*",
125   "*...................++#########++@++@@@@@@++...................*",
126   "*....................+++#######++@++@@@@+++....................*",
127   "*.....................++++#####++@@@@@++++.....................*",
128   "*.......................++++###++@@@++++.......................*",
129   "*.........................++++#++@++++.........................*",
130   "*...........................++++++++...........................*",
131   "*.............................++++.............................*",
132   "*..............................................................*",
133   "****************************************************************"};
134 
triangles()135 void triangles()
136 {
137   /* two intersecting triangles */
138   glBegin(GL_TRIANGLES);
139 
140   glColor3f(1., 0., 0.);
141   glVertex3f(-1., 1., 0.);
142   glColor4f(1., 1., 0., 0.1);
143   glVertex3f(-1., 0., 0.);
144   glColor4f(1., 0., 1., 1.0);
145   glVertex3f(1., 0., 0.2);
146 
147   glColor3f(0., 1., 0.);
148   glVertex3f(1., 0., 0.);
149   glColor3f(0., 1., 1.);
150   glVertex3f(1., 0.5, 0.);
151   glColor3f(0., 1., 1.);
152   glVertex3f(-1., 0.5, 0.1);
153 
154   glEnd();
155 }
156 
extras()157 void extras()
158 {
159   glColor3f(1., 0., 0.);
160 
161   glPointSize(1.);
162   gl2psPointSize(1.);
163   glBegin(GL_POINTS);
164   glVertex3f(-1., 1.1, 0.);
165   glEnd();
166 
167   glPointSize(3.);
168   gl2psPointSize(3.);
169   glBegin(GL_POINTS);
170   glVertex3f(-0.8, 1.1, 0.);
171   glEnd();
172 
173   glPointSize(5.);
174   gl2psPointSize(5.);
175   glBegin(GL_POINTS);
176   glVertex3f(-0.6, 1.1, 0.);
177   glEnd();
178 
179   glPointSize(7.);
180   gl2psPointSize(7.);
181   glBegin(GL_POINTS);
182   glVertex3f(-0.4, 1.1, 0.);
183   glEnd();
184 
185   glLineWidth(1.);
186   gl2psLineWidth(1.);
187   glBegin(GL_LINES);
188   glVertex3f(-0.2, 1.05, 0.);
189   glVertex3f(0.2, 1.05, 0.);
190   glEnd();
191 
192   glEnable(GL_LINE_STIPPLE);
193   glLineStipple(1, 0x087F);
194   gl2psEnable(GL2PS_LINE_STIPPLE);
195   glBegin(GL_LINES);
196   glVertex3f(-0.2, 1.15, 0.);
197   glVertex3f(0.2, 1.15, 0.);
198   glEnd();
199   glDisable(GL_LINE_STIPPLE);
200   gl2psDisable(GL2PS_LINE_STIPPLE);
201 
202   glLineWidth(3.);
203   gl2psLineWidth(3.);
204   glBegin(GL_LINES);
205   glVertex3f(0.4, 1.05, 0.);
206   glVertex3f(0.8, 1.05, 0.);
207   glEnd();
208 
209   glEnable(GL_LINE_STIPPLE);
210   glLineStipple(2, 0x0F0F);
211   /* glLineStipple(1, 0xAAAA); */
212   gl2psEnable(GL2PS_LINE_STIPPLE);
213   glBegin(GL_LINES);
214   glVertex3f(0.4, 1.15, 0.);
215   glVertex3f(0.8, 1.15, 0.);
216   glEnd();
217   glDisable(GL_LINE_STIPPLE);
218   gl2psDisable(GL2PS_LINE_STIPPLE);
219 
220   glPointSize(1);
221   gl2psPointSize(1);
222   glLineWidth(1);
223   gl2psLineWidth(1);
224 }
225 
objects()226 void objects()
227 {
228   glPushMatrix();
229   glEnable(GL_LIGHTING);
230   glRotatef(rotation, 2., 0., 1.);
231   glColor4d(0.2, 0.2, 0.9, 0.2);
232   if(teapot == GL_TRUE){
233     glutSolidTeapot(0.7);
234   }
235   else{
236     glutSolidTorus(0.3, 0.6, 20, 20);
237   }
238   glDisable(GL_LIGHTING);
239   glPopMatrix();
240 }
241 
printstring(char * string,float angle)242 void printstring(char *string, float angle)
243 {
244   unsigned int i;
245   char *fonts[] =
246     { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
247       "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique",
248       "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique",
249       "Symbol", "ZapfDingbats" };
250 
251   /* call gl2psText before the glut function since glutBitmapCharacter
252      changes the raster position... */
253   gl2psTextOpt(string, fonts[4], 12, GL2PS_TEXT_BL, angle);
254 
255   for (i = 0; i < strlen(string); i++)
256     glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, string[i]);
257 }
258 
text()259 void text()
260 {
261   double x = -1.25, y = -0.33, dy = 0.13;
262 
263   glColor3f(1., 1., 0.);
264 
265   glRasterPos2d(x, y);
266   printstring("Press:", 0.);
267   y -= dy;
268   glRasterPos2d(x, y);
269   printstring("  p: to change the print format (PS, EPS, PDF, ...)", 0.);
270   y -= dy;
271   glRasterPos2d(x, y);
272   printstring("  s: to save the images", 0.);
273   y -= dy;
274   glRasterPos2d(x, y);
275   printstring("  t: to alternate between teapot and torus", 0.);
276   y -= dy;
277   glRasterPos2d(x, y);
278   printstring("  v: to alternate between single and multiple viewport modes", 0.);
279   y -= dy;
280   glRasterPos2d(x, y);
281   printstring("  b: to change the blending mode (transparency)", 0.);
282   y -= dy;
283   glRasterPos2d(x, y);
284   printstring("  q: to quit", 0.), 0.;
285   y -= dy;
286   glRasterPos2d(x, y);
287   printstring("Click and move the mouse to rotate the objects", 0.);
288 
289   glRasterPos2d(0, 0.75);
290   printstring("rotated", 45.);
291 
292   gl2psSpecial(GL2PS_TEX, "% This should only be printed in LaTeX output!");
293 }
294 
cube()295 void cube()
296 {
297   glColor3d (0.0,1.0,0.);
298   glBegin(GL_POLYGON);
299   glVertex3d( 0.5,-0.5,-0.5);
300   glColor4d (0.0,1.0,0.,0.2);
301   glVertex3d( 0.5, 0.5,-0.5);
302   glVertex3d(-0.5, 0.5,-0.5);
303   glColor4d (0.0,1.0,0.,1);
304   glVertex3d(-0.5,-0.5,-0.5);
305   glEnd();
306 
307   glColor3d (1.0,0.0,0.);
308   glBegin(GL_POLYGON);
309   glColor4d (1.0,0.0,0.,0.1);
310   glVertex3d( 0.5,-0.5,0.5);
311   glColor4d (1.0,0.5,1.,0.9);
312   glVertex3d( 0.5, 0.5,0.5);
313   glVertex3d(-0.5, 0.5,0.5);
314   glColor4d (1.0,0.5,1.,0.1);
315   glVertex3d(-0.5,-0.5,0.5);
316   glEnd();
317   glLineWidth(4.0);
318   glColor3d (1.0,1.0,0.);
319   glBegin(GL_LINES);
320   glVertex3d( 0.5,-0.5, 0.5);
321   glVertex3d( 0.5,-0.5,-0.5);
322   glVertex3d( 0.5, 0.5, 0.5);
323   glVertex3d( 0.5, 0.5,-0.5);
324   glVertex3d(-0.5, 0.5, 0.5);
325   glVertex3d(-0.5, 0.5,-0.5);
326   glVertex3d(-0.5,-0.5, 0.5);
327   glVertex3d(-0.5,-0.5,-0.5);
328   glEnd();
329 }
330 
image(float x,float y,GLboolean opaque)331 void image(float x, float y, GLboolean opaque)
332 {
333   int w = 64, h = 66, row, col, pos = 0;
334   float *pixels, r = 0., g = 0., b = 0.;
335 
336   /* Fill a pixmap (each pixel contains three floats defining an RGB
337      color) */
338   pixels = (opaque == GL_TRUE)
339     ? (float*)malloc(3*w*h*sizeof(float))
340     : (float*)malloc(4*w*h*sizeof(float));
341 
342   for(row = h-1; row >= 0; row--){
343     for(col = 0; col < w; col++){
344       switch(pixmap[row][col]){
345       case '.' : r = 255.; g = 255.; b = 255.; break;
346       case '+' : r = 0.  ; g = 0.  ; b = 0.  ; break;
347       case '@' : r = 255.; g = 209.; b = 0.  ; break;
348       case '#' : r = 255.; g = 0.  ; b = 0.  ; break;
349       case 'a' : r = 255.; g = 209.; b = 0.  ; break;
350       case '*' : r = 0.;   g = 0.  ; b = 20. ; break;
351       }
352       r /= 255.; g /= 255.; b /= 255.;
353       pixels[pos] = r; pos++;
354       pixels[pos] = g; pos++;
355       pixels[pos] = b; pos++;
356 
357       if(opaque)
358         continue;
359 
360       switch(pixmap[row][col]){
361       case '.' : pixels[pos] = col / (float)w ; break;
362       case 'a' : pixels[pos] = 1 - col / ((float)w - 7)  ; break;
363       default  : pixels[pos] = 1.  ; break;
364       }
365       pos++;
366     }
367   }
368 
369   glRasterPos2f(x, y);
370 
371   /* call gl2psDrawPixels first since glDrawPixels can change the
372      raster position */
373   if(opaque){
374     gl2psDrawPixels((GLsizei)w, (GLsizei)h, 0, 0, GL_RGB, GL_FLOAT, pixels);
375     glDrawPixels((GLsizei)w, (GLsizei)h, GL_RGB, GL_FLOAT, pixels);
376   }
377   else{
378     gl2psDrawPixels((GLsizei)w, (GLsizei)h, 0, 0, GL_RGBA, GL_FLOAT, pixels);
379     glDrawPixels((GLsizei)w, (GLsizei)h, GL_RGBA, GL_FLOAT, pixels);
380   }
381   free(pixels);
382 }
383 
384 /* A simple drawing function, using the default viewport */
draw_single()385 void draw_single()
386 {
387   glScissor(0, 0, window_w, window_h);
388   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
389   triangles();
390   extras();
391   objects();
392   text();
393   glFlush();
394 }
395 
396 /* A more complex drawing function, using 2 separate viewports */
draw_multi()397 void draw_multi()
398 {
399   GLint viewport[4];
400 
401   glScissor(0, 0, window_w, window_h);
402   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
403 
404   /* First viewport with triangles, teapot or torus, etc. */
405   glViewport((GLint)(window_w * 0.05), (GLint)(window_h * 0.525),
406              (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
407   glScissor((GLint)(window_w * 0.05), (GLint)(window_h * 0.525),
408             (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
409   glClearColor(0.2, 0.2, 0.2, 0.);
410   glGetIntegerv(GL_VIEWPORT, viewport);
411 
412   gl2psBeginViewport(viewport);
413 
414   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
415   glMatrixMode(GL_PROJECTION);
416   glLoadIdentity();
417   glOrtho(-1.3,1.3, -1.3,1.3, -1.3,1.3);
418   glMatrixMode(GL_MODELVIEW);
419 
420   objects();
421   triangles();
422   extras();
423   text();
424 
425   gl2psEndViewport();
426 
427   /* Second viewport with cube, image, etc. */
428   glViewport((GLint)(window_w * 0.05), (GLint)(window_h * 0.025),
429              (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
430   glScissor((GLint)(window_w * 0.05), (GLint)(window_h * 0.025),
431              (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
432   glClearColor(0.8, 0.8, 0.8, 0.);
433   glGetIntegerv(GL_VIEWPORT, viewport);
434 
435   gl2psBeginViewport(viewport);
436 
437   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
438   glMatrixMode(GL_PROJECTION);
439   glLoadIdentity();
440   glOrtho(-1.3,1.3, -1.3,1.3, -1.3,1.3);
441   glMatrixMode(GL_MODELVIEW);
442 
443   glPushMatrix();
444   glRotatef(rotation, 1., 1., 1.);
445   image(-0.8, -0.3, GL_TRUE);
446   cube();
447   extras();
448   image(-0.8, 0.4, GL_FALSE);
449   glPopMatrix();
450 
451   gl2psEndViewport();
452 
453   glClearColor(0.5, 0.5, 0.5, 0.);
454   glFlush();
455 }
456 
display()457 void display()
458 {
459   GLfloat spec[4] = {0.6, 0.6, 0.6, 1.0};
460   glEnable(GL_DEPTH_TEST);
461   glDepthFunc(GL_LESS);
462   glShadeModel(GL_SMOOTH);
463   glEnable(GL_LIGHT0);
464   glEnable(GL_SCISSOR_TEST);
465   glEnable(GL_COLOR_MATERIAL);
466   glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
467   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
468   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60);
469   if(blend){
470     glEnable(GL_BLEND);
471     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
472   }
473   else{
474     glDisable(GL_BLEND);
475   }
476   if(display_multi == GL_TRUE){
477     draw_multi();
478   }
479   else{
480     draw_single();
481   }
482 }
483 
reshape(int w,int h)484 void reshape(int w, int h)
485 {
486   window_w = w;
487   window_h = h;
488 
489   glViewport(0, 0, (GLsizei)window_w, (GLsizei)window_h);
490   glMatrixMode(GL_PROJECTION);
491   glLoadIdentity();
492   glOrtho(-1.3,1.3, -1.3,1.3, -1.3,1.3);
493   glMatrixMode(GL_MODELVIEW);
494 
495   glClearColor(0.5, 0.5, 0.5, 0.);
496   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
497 }
498 
writefile(int format,int sort,int options,int nbcol,char * filename,const char * extension)499 void writefile(int format, int sort, int options, int nbcol,
500                char *filename, const char *extension)
501 {
502   FILE *fp;
503   char file[256];
504   int state = GL2PS_OVERFLOW, buffsize = 0;
505   GLint viewport[4];
506 
507   strcpy(file, filename);
508   strcat(file, ".");
509   strcat(file, extension);
510 
511   viewport[0] = 0;
512   viewport[1] = 0;
513   viewport[2] = window_w;
514   viewport[3] = window_h;
515 
516   fp = fopen(file, "wb");
517 
518   if(!fp){
519     printf("Unable to open file %s for writing\n", file);
520     exit(1);
521   }
522 
523   printf("Saving image to file %s... ", file);
524   fflush(stdout);
525 
526   while(state == GL2PS_OVERFLOW){
527     buffsize += 1024*1024;
528     gl2psBeginPage(file, "gl2psTest", viewport, format, sort, options,
529                    GL_RGBA, 0, NULL, nbcol, nbcol, nbcol,
530                    buffsize, fp, file);
531     display();
532     state = gl2psEndPage();
533   }
534 
535   fclose(fp);
536 
537   printf("Done!\n");
538   fflush(stdout);
539 }
540 
keyboard(unsigned char key,int x,int y)541 void keyboard(unsigned char key, int x, int y)
542 {
543   int opt;
544   char ext[32];
545   static int format = GL2PS_PS;
546 
547   switch(key){
548   case 27:
549   case 'q':
550     exit(0);
551     break;
552   case 't':
553     teapot = (teapot) ? GL_FALSE : GL_TRUE;
554     display();
555     break;
556   case 'p':
557     if     (format == GL2PS_PS)  format = GL2PS_EPS;
558     else if(format == GL2PS_EPS) format = GL2PS_TEX;
559     else if(format == GL2PS_TEX) format = GL2PS_PDF;
560     else if(format == GL2PS_PDF) format = GL2PS_SVG;
561     else if(format == GL2PS_SVG) format = GL2PS_PGF;
562     else                         format = GL2PS_PS;
563     printf("Print format changed to '%s'\n", gl2psGetFormatDescription(format));
564     break;
565   case 'b':
566     blend = !blend;
567     display();
568     break;
569   case 'v':
570     display_multi = display_multi ? GL_FALSE : GL_TRUE;
571     reshape(window_w, window_h);
572     display();
573     break;
574   case 's':
575     strcpy(ext, gl2psGetFileExtension(format));
576 
577     opt = GL2PS_DRAW_BACKGROUND;
578     writefile(format, GL2PS_SIMPLE_SORT, opt, 0, "outSimple", ext);
579 
580     opt = GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL;
581     writefile(format, GL2PS_SIMPLE_SORT, opt, 0, "outSimpleCulled", ext);
582 
583     opt = GL2PS_DRAW_BACKGROUND | GL2PS_NO_PS3_SHADING | GL2PS_TIGHT_BOUNDING_BOX;
584     writefile(format, GL2PS_SIMPLE_SORT, opt, 2, "outSimpleShading2", ext);
585     writefile(format, GL2PS_SIMPLE_SORT, opt, 8, "outSimpleShading8", ext);
586     writefile(format, GL2PS_SIMPLE_SORT, opt, 16, "outSimpleShading16", ext);
587 
588     opt = GL2PS_NO_TEXT;
589     writefile(format, GL2PS_SIMPLE_SORT, opt, 0, "outSimpleNoText", ext);
590 
591     opt = GL2PS_DRAW_BACKGROUND | GL2PS_BEST_ROOT;
592     writefile(format, GL2PS_BSP_SORT, opt, 0, "outBsp", ext);
593 
594     opt = GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT;
595     writefile(format, GL2PS_BSP_SORT, opt, 0, "outBspCulled", ext);
596 
597 #ifdef GL2PS_HAVE_ZLIB
598     opt = GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT | GL2PS_COMPRESS;
599     if(format == GL2PS_PS || format == GL2PS_EPS) strcat(ext, ".gz");
600     else if(format == GL2PS_SVG) strcat(ext, "z");
601     writefile(format, GL2PS_BSP_SORT, opt, 0, "outBspCulledCompressed", ext);
602 #endif
603 
604     printf("GL2PS %d.%d.%d%s done with all images\n", GL2PS_MAJOR_VERSION,
605            GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION);
606     break;
607   }
608 }
609 
motion(int x,int y)610 void motion(int x, int y)
611 {
612   rotation += 10.;
613   display();
614 }
615 
main(int argc,char ** argv)616 int main(int argc, char **argv)
617 {
618   glutInit(&argc, argv);
619   glutInitDisplayMode(GLUT_SINGLE | GLUT_DEPTH);
620   glutInitWindowSize(400, 600);
621   glutInitWindowPosition(100, 100);
622   glutCreateWindow(argv[0]);
623   glutDisplayFunc(display);
624   glutReshapeFunc(reshape);
625   glutKeyboardFunc(keyboard);
626   glutMotionFunc(motion);
627   glutMainLoop();
628   return 0;
629 }
630