/************************************************************ ************************************************************ **** **** render.cc - This file contains the inplementations of **** of the functions that are to be used to render the **** graphs and minimum spanning trees from Project 2. **** ************************************************************ ************************************************************/ extern "C" { #include #include #include #include #include } #include "Project2.h" /************************************************************ ** Ugly global variables ... Don't look behind that curtain! ************************************************************/ Graph* pG = 0; //-- pointer to "the graph" --------- vector* pPred = 0; //-- pointer to the predecessor info vector* pOrd = 0; //-- pointer to list of vert's added int first = 0; //-- for use in animation ----------- bool aniflag = false; //-- are we using animation? ---- /************************************************************ ** display() actually renders image to screen ************************************************************/ void display() { //-- Initilization ----------------------------------------// Graph &G = *pG; vector &pred = *pPred; vector &Q = *pOrd; glClear(GL_COLOR_BUFFER_BIT); //-- Write edges of graph ---------------------------------// glColor3f(0,1,1); for(int i = 0; i < G.size(); i++) for(int j = 0; j < G[i].size(); j++) { int v = G[i][j]; glBegin(GL_LINE_STRIP); glVertex2f(G[i].x,G[i].y); glVertex2f(G[v].x,G[v].y); glEnd(); } //-- Write first "first" edges in minimum spanning tree --// glColor3f(0.0,0.0,1.0); for(int k = 0; k < first && k < Q.size(); k++) { int u = Q[k]; if (pred[u] != -1) { glBegin(GL_LINE_STRIP); glVertex2f(G[pred[u]].x,G[pred[u]].y); glVertex2f(G[u].x,G[u].y); glEnd(); } } //-- Place a small square at each vertex ----------------// glColor3f(1,0,0); for(int k = 0; k < G.size(); k++) { double e = 0.005; glBegin(GL_LINE_STRIP); glVertex2f(G[k].x - e,G[k].y-e); glVertex2f(G[k].x-e,G[k].y+e); glVertex2f(G[k].x+e,G[k].y+e); glVertex2f(G[k].x+e,G[k].y-e); glVertex2f(G[k].x - e,G[k].y-e); glEnd(); } glFlush(); } /************************************************************ ** MesaGL initilization ************************************************************/ void init() { glClearColor(1.0, 1.0, 1.0, 0.0); glShadeModel(GL_FLAT); } /************************************************************ ** Deals with screen resizing ************************************************************/ void reshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0); glMatrixMode(GL_MODELVIEW); if (first > pOrd->size()) first = pOrd->size(); } /************************************************************ ** Controls each "frame" of animation. ************************************************************/ void idle(void) { if (first > pOrd->size()) sleep(1); glColor3f(0.0, 0.0, 0.0); if (aniflag) { //-- We're animating! ----------------------------------// if (!first) { glClear(GL_COLOR_BUFFER_BIT); glutPostRedisplay(); first = 1; return; } if (first <= pOrd->size()) { glutSwapBuffers(); glutPostRedisplay(); } first++; } else if (!first) { //-- We're not animating -------------------------------// first = pOrd->size(); glutPostRedisplay(); first++; } } /************************************************************ ** render(G,Pred,Ord) renders graph G along with minimum ** spanning tree edges to the vertices in Ord. The vector ** Pred gives predecessor information, i.e. if I'm looking ** at vertex v, what vertex did I come to v from? ************************************************************/ void render(Graph &G, vector &Pred, vector &Ord) { //-- Set the global variables used in Display --// pG = &G; pPred = &Pred; pOrd = &Ord; if (Ord.size() == 0) aniflag = false; /** This is some garbage to placate Mesa! **/ char s[] = "garbage"; char** tmp = new char*; *tmp = s; int tmpi = 0; /** End of garbage! **/ /******************************************* ** MESA Code *******************************************/ glutInitDisplayMode(GLUT_RGB | (aniflag ? GLUT_DOUBLE : GLUT_SINGLE)); glutInitWindowPosition(0, 0); glutInitWindowSize(600, 600); glutInit(&tmpi,tmp); glutCreateWindow("Project 2"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutIdleFunc(idle); init(); glutMainLoop(); } /************************************************************ ** These are the functions the user calls in order to have ** the rendering done. ************************************************************/ void StaticRender(Graph &G) { aniflag = false; vector T; render(G,T,T); } void StaticRender(Graph &G, vector &Pred) { aniflag = false; vector T; for(int i = 0; i < Pred.size(); i++) T.push_back(i); render(G,Pred,T); } void AnimateRender(Graph &G, vector &Pred, vector &Ord) { aniflag = true; render(G,Pred,Ord); }