Skip to content
Snippets Groups Projects
Select Git revision
  • f923de31a7b7d1b93411c9f80e31bdac2133fdf5
  • master default
  • cgnsUnstructured
  • partitioning
  • poppler
  • HighOrderBLCurving
  • gmsh_3_0_4
  • gmsh_3_0_3
  • gmsh_3_0_2
  • gmsh_3_0_1
  • gmsh_3_0_0
  • gmsh_2_16_0
  • gmsh_2_15_0
  • gmsh_2_14_1
  • gmsh_2_14_0
  • gmsh_2_13_2
  • gmsh_2_13_1
  • gmsh_2_12_0
  • gmsh_2_11_0
  • gmsh_2_10_1
  • gmsh_2_10_0
  • gmsh_2_9_3
  • gmsh_2_9_2
  • gmsh_2_9_1
  • gmsh_2_9_0
  • gmsh_2_8_6
26 results

GUI_Projection.h

Blame
  • Forked from gmsh / gmsh
    Source project has a limited visibility.
    gl2psTest.c 19.08 KiB
    /* $Id: gl2psTest.c,v 1.83 2006-10-30 17:13:46 geuzaine Exp $ */
    /*
     * GL2PS, an OpenGL to PostScript Printing Library
     * Copyright (C) 1999-2006 Christophe Geuzaine <geuz@geuz.org>
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of either:
     *
     * a) the GNU Library General Public License as published by the Free
     * Software Foundation, either version 2 of the License, or (at your
     * option) any later version; or
     *
     * b) the GL2PS License as published by Christophe Geuzaine, either
     * version 2 of the License, or (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful, but
     * WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either
     * the GNU Library General Public License or the GL2PS License for
     * more details.
     *
     * You should have received a copy of the GNU Library General Public
     * License along with this library in the file named "COPYING.LGPL";
     * if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
     * Cambridge, MA 02139, USA.
     *
     * You should have received a copy of the GL2PS License with this
     * library in the file named "COPYING.GL2PS"; if not, I will be glad
     * to provide one.
     *
     * Contributors:
     *   Rouben Rostamian <rostamian@umbc.edu>
     *   Guy Barrand <barrand@lal.in2p3.fr>
     *   Micha Bieber <bieber@traits.de>
     *
     * For the latest info about gl2ps, see http://www.geuz.org/gl2ps/.
     * Please report all bugs and problems to <gl2ps@geuz.org>.
     */
    
    /*
      To compile on Linux: 
      gcc gl2psTest.c gl2ps.c -lglut -lGL -lGLU -lX11 -lm
    
      To compile on MacOSX: 
      gcc gl2psTest.c gl2ps.c -framework OpenGL -framework GLUT -framework Cocoa
    
      (To enable file compression you must add "-DHAVE_ZLIB -lz" to the
      commands above.  To enable embedded bitmaps in SVG files you must
      add "-DHAVE_LIBPNG -DHAVE_ZLIB -lpng -lz".)
    */
    
    #ifdef _MSC_VER /* MSVC Compiler */
    #pragma comment(linker, "/entry:\"mainCRTStartup\"")
    #endif
    
    #include "gl2ps.h"
    
    #include <string.h>
    #ifdef __APPLE__
    #  include <GLUT/glut.h>
    #else
    #  include <GL/glut.h>
    #endif
    
    static float rotation = -58.;
    static GLsizei window_w = 0; 
    static GLsizei window_h = 0;
    static GLboolean display_multi = GL_TRUE;
    static GLboolean blend = GL_FALSE;
    static GLboolean teapot = GL_FALSE;
    static char *pixmap[] = {
      "****************************************************************",
      "*..............................................................*",
      "*..................++++++++++++++++++++++++++..................*",
      "*.............+++++++++++++++++++++++++++++++++++++............*",
      "*.......++++++++++++aaaaaaaaaaaaaaaaaaaaaaaa++++++++++++.......*",
      "*.......++++++aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa++++++.......*",
      "*.......++aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa++.......*",
      "*.......++aaaa++++aa+aaaaaaaa++++aaa++++++aaa+++++aaaa++.......*",
      "*.......++aaa+aaaa+a+aaaaaaa+aaaa+aa+aaaaa+a+aaaaa+aaa++.......*",
      "*.......++aa+aaaaaaa+aaaaaaaaaaa+aaa+aaaaa+a+aaaaaaaaa++.......*",
      "*.......++aa+aaa+++a+aaaaaaaaaa+aaaa++++++aaa+++++aaaa++.......*",
      "*.......++aa+aaaaa+a+aaaaaaaaa+aaaaa+aaaaaaaaaaaaa+aaa++.......*",
      "*.......++aaa+aaaa+a+aaaaaaaa+aaaaaa+aaaaaaa+aaaaa+aaa++.......*",
      "*.......++aaaa+++++a++++++aa++++++aa+aaaaaaaa+++++aaaa++.......*",
      "*.......++aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa++.......*",
      "*.......++aaaaaaaaa++++++++++++++++++++++++++aaaaaaaaa++.......*",
      "*.......++aaa+++++++@@@@@@@@@@@+++++++++++++++++++aaaa++.......*",
      "*.......++++++@@+@@@+@@@++@@@@@+++++++++++++++++++++++++.......*",
      "*.......++@@@@@+@@@+@@@+@@@@+@@+++++++++++++++++++++++++.......*",
      "*.......++@@@@+@@@+@@+++++++@@@+++++++++++++++++++++++++.......*",
      "*.......++@@@@+++++++@@@@@@++@@++#####################++.......*",
      "*.......++@+++++@@@@@@@@@@@@@@@++#####################++.......*",
      "*.......++@+++@@@@@@@@@@@@@@@@@++#####################++.......*",
      "*.......++@++@@@@@@@+@@+@@@@@@@++#####################++.......*",
      "*.......++@@@@@+@@@+@@+@@@@@@@@++#####################++.......*",
      "*.......++@@@@+@@@+@@+@@++++++++++++++++++++++++++++++++.......*",
      "*.......++@@@@+@+++++++++@++++@+@+@+++++++++++++++++++++.......*",
      "*.......++@@@@+++@@@@@@@+@++@+++@+@+@+@+++++++++++++++++.......*",
      "*.......++@++++@@@@@@@@@@+@+++@+@+@+++++++++++++++++++++.......*",
      "*.......++@+++@@@@@@@@@@+@@@@@@@@@@@@@@+++++++++++++++++.......*",
      "*.......++@++@@@@@@+@@+@+@@@+++@@@@@@@@+++++++++++++++++.......*",
      "*.......++@@@@@+@@+@@+@@+@@+++++@@@@@@@+##############++.......*",
      "*.......++@@@@+@@+@@+@@++@@+@+++@@@@@+@+##############++.......*",
      "*.......++@@@@+@+++++++@+@@@@+++@@@@++@+##############++.......*",
      "*.......++@++++++@@@@@@++@@@@+++@@@@++@+##############++.......*",
      "*.......++@+++@@@@@@@@@@+@@@+++++@@@+@@+##############++.......*",
      "*.......++@++@@@@@@@@@@@+@+++++++++++@@+##############++.......*",
      "*.......+++++++++++++++++@+@+++++++++@@+++++++++++++++++.......*",
      "*.......+++++++++++++++++@+@+@@@@++++@@+@@@@@@@@@@@@@@++.......*",
      "*.......+++++++++++++++++@@@+@@@@@+@+@@+@@@+@@+@@@@@@@++.......*",
      "*........++++++++++++++++@@@@+@@@++@++@+@@+@@+@@@+@@@++........*",
      "*........++++++++++++++++@@@@@@@@+@@+@@+@+@@+@@@+@@@@++........*",
      "*........+++++++++++++++++@@@@@@+@@+@@+@++++++++++@@@++........*",
      "*.........++##############+@@@@@@@@@@++++@@@@@@@@++@++.........*",
      "*.........++###############+@@@@@@@@++++@@@@@@@@@@@@++.........*",
      "*..........++###############++++++++@@@@@@@+@@+@@@@++..........*",
      "*..........++##################++@@@@@+@@@+@@+@@+@@++..........*",
      "*...........++#################++@@@@+@@@+@@+@@+@@++...........*",
      "*...........++#################++@@@+@@++++++++@@@++...........*",
      "*............++++++++++++++++++++@@@++++@@@@@@++@++............*",
      "*.............+++++++++++++++++++@@+++@@@@@@@@@@@+.............*",
      "*.............+++++++++++++++++++@+++@@@@@@@@@@@++.............*",
      "*..............++++++++++++++++++@++@@@@+@@@@@@++..............*",
      "*...............+++++++++++++++++@@@+@@+@@+@@@++...............*",
      "*................++++++++++++++++@@+@@+@@+@@@++................*",
      "*.................++###########++@@+++++++@@++.................*",
      "*..................++##########++@+++@@@@+@++..................*",
      "*...................++#########++@++@@@@@@++...................*",
      "*....................+++#######++@++@@@@+++....................*",
      "*.....................++++#####++@@@@@++++.....................*",
      "*.......................++++###++@@@++++.......................*",
      "*.........................++++#++@++++.........................*",
      "*...........................++++++++...........................*",
      "*.............................++++.............................*",
      "*..............................................................*",
      "****************************************************************"};
    
    void triangles(void){
      /* two intersecting triangles */
      glBegin(GL_TRIANGLES);
      
      glColor3f(1., 0., 0.);
      glVertex3f(-1., 1., 0.);
      glColor4f(1., 1., 0., 0.1);
      glVertex3f(-1., 0., 0.);
      glColor4f(1., 0., 1., 1.0);
      glVertex3f(1., 0., 0.2);
      
      glColor3f(0., 1., 0.);
      glVertex3f(1., 0., 0.);
      glColor3f(0., 1., 1.);
      glVertex3f(1., 0.5, 0.);
      glColor3f(0., 1., 1.);
      glVertex3f(-1., 0.5, 0.1);
    
      glEnd();
    }
    
    void extras(void){
      glColor3f(1., 0., 0.);
    
      glPointSize(1.);
      gl2psPointSize(1.);
      glBegin(GL_POINTS);
      glVertex3f(-1., 1.1, 0.);
      glEnd();
    
      glPointSize(3.);
      gl2psPointSize(3.);
      glBegin(GL_POINTS);
      glVertex3f(-0.8, 1.1, 0.);
      glEnd();
    
      glPointSize(5.);
      gl2psPointSize(5.);
      glBegin(GL_POINTS);
      glVertex3f(-0.6, 1.1, 0.);
      glEnd();
    
      glPointSize(7.);
      gl2psPointSize(7.);
      glBegin(GL_POINTS);
      glVertex3f(-0.4, 1.1, 0.);
      glEnd();
    
      glLineWidth(1.);
      gl2psLineWidth(1.);
      glBegin(GL_LINES);
      glVertex3f(-0.2, 1.05, 0.);
      glVertex3f(0.2, 1.05, 0.);
      glEnd();
    
      glEnable(GL_LINE_STIPPLE);
      glLineStipple(1, 0x087F);
      gl2psEnable(GL2PS_LINE_STIPPLE);
      glBegin(GL_LINES);
      glVertex3f(-0.2, 1.15, 0.);
      glVertex3f(0.2, 1.15, 0.);
      glEnd();
      glDisable(GL_LINE_STIPPLE);
      gl2psDisable(GL2PS_LINE_STIPPLE);
    
      glLineWidth(3.);
      gl2psLineWidth(3.);
      glBegin(GL_LINES);
      glVertex3f(0.4, 1.05, 0.);
      glVertex3f(0.8, 1.05, 0.);
      glEnd();
    
      glEnable(GL_LINE_STIPPLE);
      glLineStipple(2, 0x0F0F);
      /* glLineStipple(1, 0xAAAA); */
      gl2psEnable(GL2PS_LINE_STIPPLE);
      glBegin(GL_LINES);
      glVertex3f(0.4, 1.15, 0.);
      glVertex3f(0.8, 1.15, 0.);
      glEnd();
      glDisable(GL_LINE_STIPPLE);
      gl2psDisable(GL2PS_LINE_STIPPLE);
    
      glPointSize(1);
      gl2psPointSize(1);
      glLineWidth(1);
      gl2psLineWidth(1);
    }
    
    void objects(void){
      glPushMatrix();
      glEnable(GL_LIGHTING);
      glRotatef(rotation, 2., 0., 1.);
      glColor4d(0.2, 0.2, 0.9, 0.2);
      if(teapot == GL_TRUE){
        glutSolidTeapot(0.7);
      }
      else{
        glutSolidTorus(0.3, 0.6, 20, 20);
      }
      glDisable(GL_LIGHTING);
      glPopMatrix();
    }
    
    void printstring(char *string){
      unsigned int i;
      char *fonts[] = 
        { "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
          "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique",
          "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique",
          "Symbol", "ZapfDingbats" };
      
      /* call gl2psText before the glut function since glutBitmapCharacter
         changes the raster position... */
      gl2psText(string, fonts[4], 12);
    
      for (i = 0; i < strlen(string); i++)
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, string[i]);
    }
    
    void text(void){
      double x = -1.25, y = -0.33, dy = 0.13;
    
      glColor3f(1., 1., 0.);
    
      glRasterPos2d(x, y); y -= dy;
      printstring("Press:");  
      glRasterPos2d(x, y); y -= dy;
      printstring("  p: to change the print format (PS, EPS, PDF, ...)");
      glRasterPos2d(x, y); y -= dy;
      printstring("  s: to save the images");
      glRasterPos2d(x, y); y -= dy;
      printstring("  t: to alternate between teapot and torus");
      glRasterPos2d(x, y); y -= dy;
      printstring("  v: to alternate between single and multiple viewport modes");
      glRasterPos2d(x, y); y -= dy;
      printstring("  b: to change the blending mode (transparency)");
      glRasterPos2d(x, y); y -= dy;
      printstring("  q: to quit");
      glRasterPos2d(x, y); y -= dy;
      printstring("Click and move the mouse to rotate the objects");
    
      gl2psSpecial(GL2PS_TEX, "% This should only be printed in LaTeX output!");
    }
    
    void cube(void){
      glColor3d (0.0,1.0,0.);   
      glBegin(GL_POLYGON);
      glVertex3d( 0.5,-0.5,-0.5);
      glColor4d (0.0,1.0,0.,0.2);   
      glVertex3d( 0.5, 0.5,-0.5);
      glVertex3d(-0.5, 0.5,-0.5);
      glColor4d (0.0,1.0,0.,1);   
      glVertex3d(-0.5,-0.5,-0.5);
      glEnd();
    
      glColor3d (1.0,0.0,0.);   
      glBegin(GL_POLYGON);
      glColor4d (1.0,0.0,0.,0.1);   
      glVertex3d( 0.5,-0.5,0.5);
      glColor4d (1.0,0.5,1.,0.9);   
      glVertex3d( 0.5, 0.5,0.5);
      glVertex3d(-0.5, 0.5,0.5);
      glColor4d (1.0,0.5,1.,0.1);   
      glVertex3d(-0.5,-0.5,0.5);
      glEnd();
      glLineWidth(4.0);
      glColor3d (1.0,1.0,0.);   
      glBegin(GL_LINES);
      glVertex3d( 0.5,-0.5, 0.5);
      glVertex3d( 0.5,-0.5,-0.5);
      glVertex3d( 0.5, 0.5, 0.5);
      glVertex3d( 0.5, 0.5,-0.5);
      glVertex3d(-0.5, 0.5, 0.5);
      glVertex3d(-0.5, 0.5,-0.5);
      glVertex3d(-0.5,-0.5, 0.5);
      glVertex3d(-0.5,-0.5,-0.5);
      glEnd();
    }
    
    void image(float x, float y, GLboolean opaque){
      int w = 64, h = 66, row, col, pos = 0;
      float *pixels, r = 0., g = 0., b = 0.;
    
      /* Fill a pixmap (each pixel contains three floats defining an RGB
         color) */
      pixels = (opaque == GL_TRUE) 
        ? (float*)malloc(3*w*h*sizeof(float)) 
        : (float*)malloc(4*w*h*sizeof(float));
    
      for(row = h-1; row >= 0; row--){
        for(col = 0; col < w; col++){
          switch(pixmap[row][col]){
          case '.' : r = 255.; g = 255.; b = 255.; break;
          case '+' : r = 0.  ; g = 0.  ; b = 0.  ; break;
          case '@' : r = 255.; g = 209.; b = 0.  ; break;
          case '#' : r = 255.; g = 0.  ; b = 0.  ; break;
          case 'a' : r = 255.; g = 209.; b = 0.  ; break;
          case '*' : r = 0.;   g = 0.  ; b = 20. ; break;
          }
          r /= 255.; g /= 255.; b /= 255.; 
          pixels[pos] = r; pos++;
          pixels[pos] = g; pos++;
          pixels[pos] = b; pos++;
    
          if(opaque)
            continue;
    
          switch(pixmap[row][col]){
          case '.' : pixels[pos] = col / (float)w ; break;
          case 'a' : pixels[pos] = 1 - col / ((float)w - 7)  ; break;
          default  : pixels[pos] = 1.  ; break;
          }                  
          pos++;
        }
      }
    
      glRasterPos2f(x, y);
    
      /* call gl2psDrawPixels first since glDrawPixels can change the
         raster position */
      if(opaque){
        gl2psDrawPixels((GLsizei)w, (GLsizei)h, 0, 0, GL_RGB, GL_FLOAT, pixels);
        glDrawPixels((GLsizei)w, (GLsizei)h, GL_RGB, GL_FLOAT, pixels);
      }
      else{
        gl2psDrawPixels((GLsizei)w, (GLsizei)h, 0, 0, GL_RGBA, GL_FLOAT, pixels);
        glDrawPixels((GLsizei)w, (GLsizei)h, GL_RGBA, GL_FLOAT, pixels);
      }
      free(pixels);
    }
    
    /* A simple drawing function, using the default viewport */
    void draw_single(void){
      glScissor(0, 0, window_w, window_h);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      triangles();
      extras();
      objects();
      text();
      glFlush();
    }
    
    /* A more complex drawing function, using 2 separate viewports */
    void draw_multi(void){
      GLint viewport[4];
    
      glScissor(0, 0, window_w, window_h);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
      /* First viewport with triangles, teapot or torus, etc. */
      glViewport((GLint)(window_w * 0.05), (GLint)(window_h * 0.525), 
                 (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
      glScissor((GLint)(window_w * 0.05), (GLint)(window_h * 0.525), 
                (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
      glClearColor(0.2, 0.2, 0.2, 0.);
      glGetIntegerv(GL_VIEWPORT, viewport);
    
      gl2psBeginViewport(viewport);
    
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(-1.3,1.3, -1.3,1.3, -1.3,1.3);
      glMatrixMode(GL_MODELVIEW);
      
      objects();
      triangles();
      extras();
      text();
    
      gl2psEndViewport();
    
      /* Second viewport with cube, image, etc. */
      glViewport((GLint)(window_w * 0.05), (GLint)(window_h * 0.025), 
                 (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
      glScissor((GLint)(window_w * 0.05), (GLint)(window_h * 0.025), 
                 (GLsizei)(window_w * 0.9), (GLsizei)(window_h * 0.45));
      glClearColor(0.8, 0.8, 0.8, 0.);
      glGetIntegerv(GL_VIEWPORT, viewport);
    
      gl2psBeginViewport(viewport);
    
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(-1.3,1.3, -1.3,1.3, -1.3,1.3);
      glMatrixMode(GL_MODELVIEW);
    
      glPushMatrix();
      glRotatef(rotation, 1., 1., 1.);
      image(-0.8, -0.3, GL_TRUE);
      cube();
      extras();
      image(-0.8, 0.4, GL_FALSE);
      glPopMatrix();
    
      gl2psEndViewport();
    
      glClearColor(0.5, 0.5, 0.5, 0.);
      glFlush();
    }
    
    void display(void){
      GLfloat spec[4] = {0.6, 0.6, 0.6, 1.0};
      glEnable(GL_DEPTH_TEST);
      glDepthFunc(GL_LESS);
      glShadeModel(GL_SMOOTH);
      glEnable(GL_LIGHT0);
      glEnable(GL_SCISSOR_TEST);
      glEnable(GL_COLOR_MATERIAL);
      glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
      glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60);
      if(blend){
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      }
      else{
        glDisable(GL_BLEND);
      }
      if(display_multi == GL_TRUE){
        draw_multi();
      }
      else{
        draw_single();
      }
    }
    
    void reshape(int w, int h){
      window_w = w;
      window_h = h;
    
      glViewport(0, 0, (GLsizei)window_w, (GLsizei)window_h);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(-1.3,1.3, -1.3,1.3, -1.3,1.3);
      glMatrixMode(GL_MODELVIEW);
    
      glClearColor(0.5, 0.5, 0.5, 0.);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }
    
    void writefile(int format, int sort, int options, int nbcol,
                   char *filename, const char *extension){
      FILE *fp;
      char file[256];
      int state = GL2PS_OVERFLOW, buffsize = 0;
      GLint viewport[4];
    
      strcpy(file, filename);
      strcat(file, ".");
      strcat(file, extension);
    
      viewport[0] = 0;
      viewport[1] = 0;
      viewport[2] = window_w;
      viewport[3] = window_h;
     
      fp = fopen(file, "wb");
    
      if(!fp){
        printf("Unable to open file %s for writing\n", file);
        exit(1);
      }
    
      printf("Saving image to file %s... ", file);
      fflush(stdout);
    
      while(state == GL2PS_OVERFLOW){
        buffsize += 1024*1024;
        gl2psBeginPage(file, "gl2psTest", viewport, format, sort, options,
                       GL_RGBA, 0, NULL, nbcol, nbcol, nbcol, 
                       buffsize, fp, file);
        display();
        state = gl2psEndPage();
      }
    
      fclose(fp);
    
      printf("Done!\n");
      fflush(stdout);
    }
    
    void keyboard(unsigned char key, int x, int y){
      int opt;
      char ext[32];
      static int format = GL2PS_PS;
    
      switch(key){
      case 27:
      case 'q':
        exit(0);
        break;
      case 't':
        teapot = (teapot) ? GL_FALSE : GL_TRUE;
        display();
        break;
      case 'p':
        if     (format == GL2PS_PS)  format = GL2PS_EPS;
        else if(format == GL2PS_EPS) format = GL2PS_TEX;
        else if(format == GL2PS_TEX) format = GL2PS_PDF;
        else if(format == GL2PS_PDF) format = GL2PS_SVG;
        else if(format == GL2PS_SVG) format = GL2PS_PGF;
        else                         format = GL2PS_PS;
        printf("Print format changed to '%s'\n", gl2psGetFormatDescription(format));
        break;
      case 'b':
        blend = !blend;
        display();
        break;
      case 'v':
        display_multi = display_multi ? GL_FALSE : GL_TRUE;
        reshape(window_w, window_h);
        display();
        break;
      case 's':
        strcpy(ext, gl2psGetFileExtension(format));
    
        opt = GL2PS_DRAW_BACKGROUND;
        writefile(format, GL2PS_SIMPLE_SORT, opt, 0, "outSimple", ext);
    
        opt = GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL;
        writefile(format, GL2PS_SIMPLE_SORT, opt, 0, "outSimpleCulled", ext);
    
        opt = GL2PS_DRAW_BACKGROUND | GL2PS_NO_PS3_SHADING | GL2PS_TIGHT_BOUNDING_BOX;
        writefile(format, GL2PS_SIMPLE_SORT, opt, 2, "outSimpleShading2", ext);
        writefile(format, GL2PS_SIMPLE_SORT, opt, 8, "outSimpleShading8", ext);
        writefile(format, GL2PS_SIMPLE_SORT, opt, 16, "outSimpleShading16", ext);
    
        opt = GL2PS_NO_TEXT;
        writefile(format, GL2PS_SIMPLE_SORT, opt, 0, "outSimpleNoText", ext);
    
        opt = GL2PS_DRAW_BACKGROUND | GL2PS_BEST_ROOT;
        writefile(format, GL2PS_BSP_SORT, opt, 0, "outBsp", ext);
    
        opt = GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT;
        writefile(format, GL2PS_BSP_SORT, opt, 0, "outBspCulled", ext);
    
    #ifdef GL2PS_HAVE_ZLIB
        opt = GL2PS_DRAW_BACKGROUND | GL2PS_OCCLUSION_CULL | GL2PS_BEST_ROOT | GL2PS_COMPRESS;
        if(format == GL2PS_PS || format == GL2PS_EPS) strcat(ext, ".gz");
        else if(format == GL2PS_SVG) strcat(ext, "z");
        writefile(format, GL2PS_BSP_SORT, opt, 0, "outBspCulledCompressed", ext);
    #endif
    
        printf("GL2PS %d.%d.%d%s done with all images\n", GL2PS_MAJOR_VERSION, 
               GL2PS_MINOR_VERSION, GL2PS_PATCH_VERSION, GL2PS_EXTRA_VERSION);
        break;
      }
    }
    
    void motion(int x, int y){
      rotation += 10.;
      display();
    }
    
    int main(int argc, char **argv){
      glutInit(&argc, argv);
      glutInitDisplayMode(GLUT_SINGLE | GLUT_DEPTH);
      glutInitWindowSize(400, 600);
      glutInitWindowPosition(100, 100);
      glutCreateWindow(argv[0]);
      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
      glutKeyboardFunc(keyboard);
      glutMotionFunc(motion);
      glutMainLoop();
      return 0;
    }