/***************************************************************************** Some simple SGI GL-based routines for CS480 ****************************************************************************** Author: Stan Sclaroff Boston University Computer Science Dept. January 27, 1995 ****************************************************************************** Modifications: Feb. 15, 1995, Modified for programming assignment 2 Added: support for polylines and rectangular frames Removed: pixmap stuff Changed: line drawing to use GL line drawing routines ******************************************************************************/ #include #include #include #include #include "draw.h" /* This routine opens a window. Returns window id. If window open fails, then it returns window id = 0 */ long open_window(width,height,name) long width,height; char *name; { long winid; /* put the graphical process in the foreground so that we can interact with it */ foreground(); /* set the prefered size of the window */ prefsize(width,height); /* open the window, return 0 if failure */ winid = winopen(name); if (winid == 0) { fprintf(stderr,"Cannot open window\n"); return(0); } /* configure the window with double buffer */ doublebuffer(); gconfig(); /* clear both of the double buffers */ clear(); swapbuffers(); clear(); /* specify clipping region */ ortho2(0,width,0,height); /* select devices to queue */ qdevice(REDRAW); return(winid); } /* close a window */ void close_window(winid) long winid; /* the window id */ { winclose(winid); } /* routine to clip and draw a polyline */ clip_draw_polyline(winid,poly,frame) long winid; /* the window id */ Polyline *poly; /* polyline data structure */ Frame *frame; /* clipping frame data structure */ { int i; float *p0,*p1; /* start with the first line segment */ p0 = poly->points; p1 = &p0[2]; for(i=0;in_lines;++i) { /* clip and draw it */ clip2d(winid,p0[0],p0[1],p1[0],p1[1], frame->xmin,frame->ymin,frame->xmax,frame->ymax,poly->color); /* increment to next line segment */ p0 = p1; p1 = &p0[2]; } } /* draw one line to a GL window */ draw_line(winid,p0,p1,value) long winid; /* the window id */ float p0[2],p1[2]; /* the start and end points of the line */ Colorindex value; /* the desired line color */ { winset(winid); /* set the current window */ color(value); /* set the appropriate color */ bgnline(); /* GL command to begin a line */ v2f(p0); /* first vertex */ v2f(p1); /* second vertex */ endline(); /* end the line */ } /* draw a frame to the window in the appropriate color */ draw_frame(winid,frame) long winid; /* the window id */ Frame *frame; /* frame data structure */ { int i; float p[2]; winset(winid); /* set the window */ color(frame->color); /* set appropriate color */ bgnline(); /* begin the polyline */ /* first point */ p[0] = frame->xmin; p[1] = frame->ymin; v2f(p); /* second, etc... */ p[1] = frame->ymax; v2f(p); p[0] = frame->xmax; v2f(p); p[1] = frame->ymin; v2f(p); p[0] = frame->xmin; v2f(p); endline(); /* end the line */ } /* create a polyline, given points, center, and desired color */ Polyline *create_polyline(points,num_points,center,color) float *points,*center; /* the polyline's points and the center point */ int num_points; /* number of polyline points */ Colorindex color; /* desired color */ { Polyline *poly; /* allocate the memory */ poly = (Polyline *)malloc(sizeof(Polyline)); /* fill in the data structure */ /* use the points sent in by the caller */ poly->n_lines = num_points - 1; poly->points = points; poly->color = color; poly->center[0] = center[0]; poly->center[1] = center[1]; } /* free a polyline */ void free_polyline(poly) Polyline *poly; { if(poly!=0) { if(poly->points!=0) free(poly->points); free(poly); } } /* read an allocate polyline from a text file */ Polyline *read_polyline_file(fname,color) char *fname; Colorindex color; { Polyline *poly; int i,n; float x,y,center[2],*points; FILE *f; /* open the polyline text file */ f = fopen(fname,"r"); if(f==0) { fprintf(stderr,"Error reading polyline file: cannot find file\n"); return(0); } /* first record is the center point */ fscanf(f,"%f %f\n",¢er[0],¢er[1]); /* second is the number of points */ fscanf(f,"%d\n",&n); /* allocate the points array (2-D) */ points = (float *)malloc(sizeof(float)*n*2); /* read in the points from the file */ for(i=0;ixmax = xmax; frame->ymax = ymax; frame->xmin = xmin; frame->ymin = ymin; frame->color = color; return(frame); } /* free a frame structure */ void free_frame(frame) Frame *frame; { if(frame!=0) free(frame); } /* routine to transform, clip and then draw the polyline */ /* also draw the bounding frame */ redraw(winid,poly,u,frame) long winid; Polyline *poly; Frame *frame; float *u; { Polyline *res; float *points; int n_points; /* make a duplicate polyline structure to hold the transformed result */ n_points = poly->n_lines + 1; points = (float *)calloc(sizeof(float),2*n_points); res = create_polyline(points,n_points,poly->center,poly->color); /* set the current window to be the draw window */ winset(winid); reshapeviewport(); /* clear the window */ color(BLACK); clear(); /* transform the polyline */ transform_polyline(poly,u,res); /* clip and draw the polyline */ clip_draw_polyline(winid,res,frame); /* draw the frame */ draw_frame(winid,frame); /* we're drawing in double-buffer mode, swap buffers */ swapbuffers(); }