Select Git revision
GFaceCompound.cpp
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;
}