/******************************************************************* Callbacks for GLUT and sundry utilities ******************************************************************** Author: Stan Sclaroff, Ashwin Thangali and John Isidoro Comments: Provided for CS480/CS680 programming assignment #1. ********************************************************************/ #include #include #include #include #include #include "types.h" #include "funcs.h" /* global variables -- static for storing state */ static int renderFlags=0; static int test_case; static int Nsteps = 18; static Vertex tri[3]; static Vertex line[2]; static int triangle_vertex_count=0; static int line_vertex_count=0; static Color current_color; /* Macro for copying color */ #define COPYCOLOR(A,B) {(A).r = (B).r;(A).g=(B).g;(A).b=(B).b;} /* initialize the system */ void init(int width, int height) { initPixelBuffer(width,height); clearPixelBuffer(); current_color.r = current_color.g = current_color.b = 255; /* white */ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); } /* display contents of the Pixel buffer */ void display(void) { glRasterPos2i(0, 0); glDrawPixels(getPixelBufferWidth(), getPixelBufferHeight(), GL_RGB, GL_UNSIGNED_BYTE, getPixelBufferAddress()); glFlush(); } /* called at initialization and whenever user resizes the window */ void reshape(int w, int h) { int pbWidth = getPixelBufferWidth(), pbHeight = getPixelBufferWidth(); /* do not allow size of window other than Pixel buffer size */ if(w != pbWidth || h != pbHeight) glutReshapeWindow(pbWidth,pbHeight); glViewport(0, 0, (GLsizei) pbWidth, (GLsizei) pbHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble) pbWidth, 0.0, (GLdouble) pbHeight); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* handle mouse button clicks */ void mouseButton(int button, int state, int x, int y) { static int ox,oy; int screeny; Color color; screeny = getPixelBufferHeight() - y; if (state == GLUT_UP) /* take position on "button up" */ { switch(button){ case GLUT_LEFT_BUTTON: /* add a triangle vertex */ /* initial vertex */ if(triangle_vertex_count==0) { tri[0].x = x; tri[0].y = screeny; COPYCOLOR(tri[0].color,current_color); triangle_vertex_count = 1; setPixel(x,screeny,current_color); glutPostRedisplay(); } /* second vertex */ else if(triangle_vertex_count==1) { tri[1].x = x; tri[1].y = screeny; COPYCOLOR(tri[1].color,current_color); setPixel(x,screeny,current_color); triangle_vertex_count = 2; glutPostRedisplay(); } /* last vertex closes triangle */ else { tri[2].x = x; tri[2].y = screeny; COPYCOLOR(tri[2].color,current_color); drawTriangle(tri,renderFlags); triangle_vertex_count = 0; glutPostRedisplay(); } break; case GLUT_MIDDLE_BUTTON: /* unused in this assignment */ break; case GLUT_RIGHT_BUTTON: /* line end points */ if(line_vertex_count==1) { line[1].x = x; line[1].y = screeny; COPYCOLOR(line[1].color,current_color); drawLine(line[0],line[1]); line_vertex_count=0; glutPostRedisplay(); } else if(line_vertex_count==0) { line[0].x = x; line[0].y = screeny; COPYCOLOR(line[0].color,current_color); setPixel(x,screeny,current_color); line_vertex_count=1; glutPostRedisplay(); } default: break; } } } void drawTestCase() { /* clear the window and vertex state */ clearPixelBuffer(); triangle_vertex_count = 0; line_vertex_count = 0; switch (test_case){ case 0: lineTestPattern1(); break; case 1: lineTestPattern2(); break; case 2: lineTestPattern3(); break; case 3: triTestPattern1(0); /*single color polygon*/ break; case 4: triTestPattern1(SMOOTH_SHADING_BIT); /*smooth shaded polygon*/ break; case 5: triTestPattern2(0); /*single color polygon*/ break; case 6: triTestPattern2(SMOOTH_SHADING_BIT); /*smooth shaded polygon*/ break; } glutPostRedisplay(); } /* handles input from the keyboard */ void keyboard(unsigned char key, int x, int y) { Color color; switch(key){ case 'c': case 'C': /* c or C key = clear state, clear buffer */ clearPixelBuffer(); triangle_vertex_count = 0; line_vertex_count = 0; glutPostRedisplay(); break; case 'q': case 'Q': case 27: /* Esc, q, or Q key = Quit */ exit(0); break; case 'l': case 'L': /* l or L key = line test pattern */ if( test_case > 2 ) test_case = 0; else test_case = (test_case + 1 )%3; drawTestCase(); break; case 't': case 'T': /* t or T key = triangle test pattern */ if( test_case < 3 ) test_case = 3; else test_case = (test_case + 1 - 3)%4 + 3; drawTestCase(); break; case 's': case 'S': renderFlags^=SMOOTH_SHADING_BIT; printf("Renderflags = %d",renderFlags); break; case 'x': case 'X': renderFlags^=TEXTURE_MAPPING_BIT; break; case 'r': case 'R': current_color.r+=16; current_color.r&=255; printf("Color is now %d,%d,%d\n", current_color.r,current_color.g,current_color.b); break; case 'g': case 'G': current_color.g+=16; current_color.g&=255; printf("Color is now %d,%d,%d\n", current_color.r,current_color.g,current_color.b); break; case 'b': case 'B': current_color.b+=16; current_color.b&=255; printf("Color is now %d,%d,%d\n", current_color.r,current_color.g,current_color.b); break; case '<': Nsteps = Nsteps / 2; if( Nsteps < 3 ) Nsteps = 3; printf( "Nsteps = %d \n", Nsteps); drawTestCase(); break; case '>': Nsteps = Nsteps * 2; if( Nsteps > 1000 ) Nsteps = 1000; printf( "Nsteps = %d \n", Nsteps); drawTestCase(); break; default: break; } } #define PI 3.1415927 #ifndef M_PI #define M_PI 3.1415927 #endif /* draw a test line pattern to see if all quadrants and +/- slopes work */ void lineTestPattern1(void) { float theta,delta; float radius; int cx,cy,x,y; int i,n_steps = ( Nsteps == 18 )?9:Nsteps; Vertex v0,v1,v2; delta = -PI/n_steps; radius = getPixelBufferWidth()*0.45; /* center of pattern */ v0.x = cx = getPixelBufferWidth()/2.0; v0.y = cy = getPixelBufferHeight()/2.0; v0.color.r = v0.color.g = 255; v0.color.b = 0; for(i=0,theta=0;i 1 ) distanceScale = 1; if( distanceScale < 0 ) distanceScale = 0; temp=0; if( normal == NULL ){ temp += x* lvx; temp += y* lvy; temp += z* lvz; dotProd[i] = distanceScale * temp /( rad * temp1) ; } else { temp += normal[0] * lvx; temp += normal[1] * lvy; temp += normal[2] * lvz; dotProd[i] = distanceScale * temp / temp1; } } for(j=0;j<3;j++) col[j] = 0; for(i=0; i 0 ){ temp = dotProd[i]; for(j=0;j<3;j++) col[j] += lights[i][4+j] * temp; } } for(j=0;j<3;j++){ if( col[j] > 1 ) col[j] = 1; col[j] = col[j] * 255; } i=i; }