#include #include #include #include #include #include #define WORLD_WIDTH 10 #define WORLD_HEIGHT 10 static int WindowWidth = 512; static int WindowHeight = 512; static int MainWindow = 0; static int SecondWindow = 0; void Reshape(int width, int height) { /* glViewport defines part of the window we are going to use */ /* we are going to use the whole window */ WindowWidth = width; WindowHeight = height; glViewport(0,0,width,height); /* initialize the viewing transformation (camera position) to identity; this corresponds to camera looking down negative z axis */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* specify the projection transformation (camera parameters); */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* this defines a camera with orthogonal projection that captures the part of the virtual world inside the box from -WORLD_WIDTH/2 to WORLD_WIDTH/2 in the X direction -WORLD_HEIGHT/2 to WORLD_HEIGHT/2 in the Y direction and from 0 to 1 (default in Z direction */ gluOrtho2D(-WORLD_WIDTH/2, WORLD_WIDTH/2,-WORLD_HEIGHT/2,WORLD_HEIGHT/2); } /* draw coordinate axes along X and Y; X in green Y in blue */ void drawAxes() { glBegin(GL_LINES); /* x axis */ glColor3d( 0,1,0); glVertex3d(-WORLD_WIDTH/2,0,0); glVertex3d(WORLD_WIDTH/2,0,0); /* y axis */ glColor3d( 0,0,1); glVertex3d(0,-WORLD_HEIGHT/2,0); glVertex3d(0,WORLD_HEIGHT/2,0); glEnd(); } struct Point { double x,y,z; }; #define MAX_POINTS 1000 static int NumPoints = 0; static struct Point Points[MAX_POINTS]; static int CurrentPoint = -1; /* some constants we are going to use in our drawing routines */ static double LightBlue[] = { 0.5,0.5,1.0 }; static double LightRed[] = { 1.0,0.5,0.5 }; /* window redraw even callback; is called when the window is created, maximized, resized etc.; also called if glutPostRedisplay generates the necessary event */ void Draw() { int i; /* in the double buffer mode all drawing happens in the invisible back buffer */ glClearColor( 0.0, 0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); drawAxes(); glPointSize(5.0); glColor3dv(LightBlue); glBegin(GL_POINTS); for( i = 0; i < NumPoints; i++ ) { if( i == CurrentPoint ) glColor3dv(LightRed); glVertex3d( Points[i].x,Points[i].y,Points[i].z); if( i == CurrentPoint ) glColor3dv(LightBlue); } glEnd(); /* once we are done drawing we swap the back and front buffers */ glutSwapBuffers(); } /* callback for button clicks; gets called each time a mouse button is pressed or released */ #define EPSILON 1 void Mouse( int button, int state, int x, int y) { int modifiers; int i; double xclicked, yclicked; modifiers = glutGetModifiers(); if( button == GLUT_LEFT_BUTTON ) { if( state == GLUT_UP ) { } else if (state == GLUT_DOWN) { if( modifiers & GLUT_ACTIVE_SHIFT ) { if( NumPoints < MAX_POINTS ) { Points[NumPoints].x = WORLD_WIDTH*( x/(double)WindowWidth - 0.5 ); Points[NumPoints].y = WORLD_HEIGHT*( 0.5-y/(double)WindowHeight); Points[NumPoints].z = 0.0; NumPoints++; } } else { /* shift not pressed */ xclicked = WORLD_WIDTH*( x/(double)WindowWidth - 0.5 ); yclicked = WORLD_HEIGHT*( 0.5-y/(double)WindowHeight); i = 0; while( i < NumPoints && ( ( fabs( xclicked - Points[i].x) > EPSILON ) || ( fabs( yclicked - Points[i].y) > EPSILON ) )) i++; if( i == NumPoints ) CurrentPoint = -1; else CurrentPoint = i; } /* as we are using several windows we have to indicate which one we want to redraw */ glutPostWindowRedisplay(MainWindow); } else { assert(0); } } else if( button == GLUT_MIDDLE_BUTTON ) { } else if( button == GLUT_RIGHT_BUTTON) { if( state == GLUT_UP ) { } else if (state == GLUT_DOWN) { } else { assert(0); } } else { assert(0); } } Motion(int x, int y) { if( CurrentPoint != -1 ) { Points[CurrentPoint].x = WORLD_WIDTH*( x/(double)WindowWidth - 0.5 ); Points[CurrentPoint].y = WORLD_HEIGHT*( 0.5-y/(double)WindowHeight); /* as we are using several windows we have to indicate which one we want to redraw */ glutPostWindowRedisplay(MainWindow); } } /* callbacks for the second window */ void Draw2() { glClearColor( 1.0, 0.0,0.0,1.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glutSwapBuffers(); } void Reshape2( int width, int height ) { } int main(int argc, char* argv[]) { /* initialize glut and parse command-line aguments that glut understands */ glutInit(&argc, argv); /* initialize dislay mode: 4 color components, double buffer and depth buffer */ glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); glutInitWindowSize(256,256); /* CreateWindow returns a window id which can be used in PostWindowRedisplay */ MainWindow = glutCreateWindow("a simple window "); /* register all callbacks */ glutDisplayFunc(Draw); glutReshapeFunc(Reshape); glutMouseFunc(Mouse); glutMotionFunc(Motion); /* create a second window next to the first */ glutInitWindowPosition(256,0); SecondWindow = glutCreateWindow("the second window "); glutDisplayFunc(Draw2); glutReshapeFunc(Reshape2); /* this is an infinte loop get event - dispatch event which never returns */ glutMainLoop(); return 0; }