All pastes #183663 Raw Edit

Stuff

public c v1 · immutable
#183663 ·published 2006-09-27 02:55 UTC
rendered paste body
/* Assignment 1 - Duy Nguyen: September 12, 2006 *  This program draws a grid and allows the user to draw lines and polygons. * It handles techniques to draw lines at the pixel level, as well as filling * polygons as required. * *  Just to note, this program uses triangle.c as a template for many of the *  Glut functions. */#include <stdio.h>       #include <stdlib.h>      #include <string.h> /*// Sometimes glu.h includes glut.h--sometimes not.*/#ifdef MAC_OSX#    include <OpenGL/glu.h>#    include <GLUT/glut.h>#else #    include <GL/glu.h>       #    include <GL/glut.h>       #endiftypedef enum DQN_object{    DQN_LINE,     DQN_POLY} DQN_object;/* -------------------------------------------------------------------------- */// Function Declarationsstatic void display_CB(void);            /* Called whenever redisplay needed */static void key_CB(unsigned char key, int x, int y);     /* Called on key press */static void mouse_CB(int button, int state, int x, int y);  /* Called on mouse click */static void add_object_CB(int value);static void runCommand(char* s); /* Reads a line and adds it to the list of shapes */static void drawGrid();    /* Draw grid */static void drawLine(int x1, int y1, int x2, int y2); /* Draw a specified Line */static void drawPoly(int* x, int* y, int size); /*Draw a specified Polygon */static void fillPixel(int x, int y); //Fill a Pixelstatic void addLine(int x1, int y1, int x2, int y2); /*add line to current list*/static void addPoly(int x, int y, int size);  /*add polygon to current list*/static void changeColor(); /* upgrade color*/static void parseFile();static void saveFile();/* -------------------------------------------------------------------------- */// Instance Variable Declarationsstatic int first_x = -1;static int first_y = -1;  //Current Colorsstatic float cur_red = 1.0; static float cur_green = 1.0; static float cur_blue = 1.0; static int cellSize = 30; //Pixel size of cellsstatic int gridWidth = 21; static int gridHeight = 21;static char commands[1000][500];static int cmSize = 0;static int polyX[100];static int polyY[100];static int polySize = 0;static int colorSwitch = 0;static int mode = 0; /* 0 means line-draw mode, 1 means poly-draw mode *//* -------------------------------------------------------------------------- */int main(int argc, char *argv[]){    int win;    int submenu;    glutInit(&argc, argv);                /* initialize GLUT system */    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);    glutInitWindowSize(630, 630);     win = glutCreateWindow("Assignment 1");   /* create window */    /* set background to black */    glClearColor((GLclampf)0.0,(GLclampf)0.0,(GLclampf)0.0,(GLclampf)0.0);      gluOrtho2D(0.0, 630.0, 0.0, 630.0); /* how object is mapped to window */    glutDisplayFunc(display_CB);        /* set window's display callback */    glutKeyboardFunc(key_CB);           /* set window's key callback */    glutMouseFunc(mouse_CB);            /* set window's mouse callback */    /* Create a menu which is accessed by the right button. */    glutCreateMenu(add_object_CB);    glutAddMenuEntry("Line Mode", DQN_LINE);    glutAddMenuEntry("Polygon Mode", DQN_POLY);    glutAttachMenu(GLUT_RIGHT_BUTTON);    parseFile(); // Read in any predone code    glutMainLoop();                       /* start processing events... */    /* Execution never reaches this point, so return value is failure */    return EXIT_FAILURE;}static void parseFile(){	if(!isatty(fileno(stdin)))	{		char* temp[500];		while( fgets(temp, 500, stdin) != NULL)		{			strcpy(&commands[cmSize], temp);			cmSize++;		}	}}static void saveFile(){	int i = 0;	for(i = 0; i < cmSize; i++)	{		printf("%s", commands[i]);	}}static void runCommand(char* s){	const char delimiters[] = " ";	char* token;	char cp[500];	strcpy (cp, s);        	token = strtok (cp, delimiters);	if( strcmp(token, "line") == 0)	{		glColor3d(.8, .8, .8); 		int a = atoi(strtok (NULL, delimiters));		int b = atoi(strtok (NULL, delimiters));		int c = atoi(strtok (NULL, delimiters));		int d = atoi(strtok (NULL, delimiters));		drawLine(a,b,c,d);	}	else if ( strcmp(token, "poly") == 0)	{		changeColor();		glColor3d(cur_red, cur_green, cur_blue); 				int xPol[100];		int yPol[100];		int pSize = 0;		token = strtok(NULL, delimiters);		while( token != NULL)		{			xPol[pSize] = atoi(token);			yPol[pSize] = atoi(strtok(NULL, delimiters));			pSize++;			token = strtok(NULL, delimiters);		}		drawPoly(xPol, yPol, pSize);			}	}// Draws a grid on the displaystatic void drawGrid(){    int i = 0;    int j = 0;    glColor3d(.7, .7, .7); //Set Color to Grey    glBegin(GL_LINES); //Start Draw    for( i = 0; i < gridWidth; i++)    {        for(j = 0; j < gridHeight; j++)        {		    glVertex3f( i*cellSize, j*cellSize+(cellSize-1), 0);				// Top Left		    glVertex3f( i*cellSize+(cellSize-1), j*cellSize+(cellSize-1), 0);				// Top Right		    glVertex3f( i*cellSize+(cellSize-1), j*cellSize+(cellSize-1), 0);				// Top Right		    glVertex3f( i*cellSize+(cellSize-1), j*cellSize, 0);				// Bot Right		    glVertex3f( i*cellSize+(cellSize-1), j*cellSize, 0);				// Bot Right		    glVertex3f( i*cellSize, j*cellSize, 0);				// Bot Left		    glVertex3f( i*cellSize, j*cellSize, 0);				// Bot Left		    glVertex3f( i*cellSize, j*cellSize+(cellSize-1), 0);				// Top Left	        }    }    glEnd(); //End Draw} /* Draw a specified Line */static void drawLine(int x1, int y1, int x2, int y2){	int x = x1;	int y = y1;	int xEnd = x2;	int yEnd = y2;	//Make sure we are always drawing from left to right	if (x1 > x2)	{		x = x2;		xEnd = x1;		y = y2;		yEnd = y1;	}	else if ( x1 == x2)	{		if( y1 < y2)		{			x = x2;			xEnd = x1;			y = y2;			yEnd = y1;		}	}		int dx = xEnd - x;	int dy = yEnd - y;	if(dx*dy > 0) //positive slope	{		if( dx >= dy) // Slope is between 1 and 0		{			int p = 2*dy - dx;			fillPixel(x,y);			while( x != xEnd)			{				x++;				if(p > 0)				{					y = y+1;					fillPixel(x,y);					p = p+2*dy-2*dx;				}				else				{					fillPixel(x,y);					p = p+2*dy;				}			}			}		else //Slope is greater than 1		{			int p = 2*dx - dy;			fillPixel(x,y);			while( y != yEnd)			{				y++;				if(p > 0)				{					x = x+1;					fillPixel(x,y);					p = p+2*dx-2*dy;				}				else				{					fillPixel(x,y);					p = p+2*dx;				}			}		}	}	else			//Negative slope	{		if( dx >= abs(dy)) //Flatter Slope		{			dy = abs(dy);			int p = 2*dy - dx;			fillPixel(x,y);			while( x != xEnd)			{				x++;				if(p > 0)				{					y = y-1;					fillPixel(x,y);					p = p+2*dy-2*dx;				}				else				{					fillPixel(x,y);					p = p+2*dy;				}			}			}		else	//Taller Slope		{			dy = abs(dy);			int p = 2*dx - dy;			fillPixel(x,y);			while( y != yEnd)			{				y--;				if(p > 0)				{					x = x+1;					fillPixel(x,y);					p = p+2*dx-2*dy;				}				else				{					fillPixel(x,y);					p = p+2*dx;				}			}		}					}}//Draw a polygonstatic void drawPoly(int* x, int* y, int size){	int i;	x[size] = x[0];	y[size] = x[0];	for(i = 0; i < size; i++)	{		int x1 = x[i];		int y1 = y[i];		int x2 = x[(i+1)%size];		int y2 = y[(i+1)%size];		drawLine(x1, y1, x2, y2);	}	//Find row min and row max	int rMin = 20;	int rMax = -20;	for(i = 0; i < size; i++)	{		if(y[i] > rMax)			rMax = y[i];		if(y[i] < rMin)			rMin = y[i];	}	int index = rMax - rMin +1;	//Compile edge table	int xA[index];	int xA_num[index];	int dxA[index];	int dyA[index];	int yA[index];	int xB[index];	int xB_num[index];	int dxB[index];	int dyB[index];	int yB[index];	for( i = 0; i < index; i++)	{		xA[i] = -999;		xA_num[i]= -999;		dxA[i]= -999;		dyA[i]= -999;		yA[i]= -999;		xB[i]= -999;		xB_num[i]= -999;		dxB[i]= -999;		dyB[i]= -999;		yB[i]= -999;	}	//Look at each edge	for(i = 0; i < size; i++)	{		int x1 = x[i];		int x2 = x[(i+1)%size];		int y1 = y[i];		int y2 = y[(i+1)%size];		//ignore horizontal lines		if( y1 != y2)		{			if( y1 < y2)			{				//printf("hit\n");				if(dxA[i] == -999)				{					printf("%d\n", y1);					xA[y1] = x1;					xA_num[y1] = 0;					dxA[y1] = x2-x1;					dyA[y1] = y2-y1;					yA[y1] = y2;				}				else				{					xB[y1] = x1;					xB_num[y1] = 0;					dxB[y1] = x2-x1;					dyB[y1] = y2-y1;					yB[y1] = y2;				}			}			else			{				if(dxA[i] == -999)				{					xA[y2] = x2;					xA_num[y2] = 0;					dxA[y2] = x1-x2;					dyA[y2] = y1-y2;					yA[y2] = y1;				}				else				{					xB[y2] = x2;					xB_num[y2] = 0;					dxB[y2] = x1-x2;					dyB[y2] = y1-y2;					yB[y2] = y1;				}			}		}	}	//Build Active Edge List	//For Each Row	for(i = 0; i < index; i ++)	{		if(dxA[i] != -999)		{			int nextY = i + 1;						//If the next row is not max			if( nextY < yA[i])			{				//copy displacement and max				dxA[nextY] = dxA[i];				dyA[nextY] = dyA[i];				yA[nextY] = yA[i];				//Calculate X's				int x_int = xA[i];				int num = xA_num[i] + dxA[i];								if( num >= dyA[i])				{					xA[nextY] = xA[i] + 1;					num = num - dyA[i];				}								xA_num[nextY] = num;			}		}		if(dxB[i] != -999)		{			int nextY = i + 1;						//If the next row is not max			if( nextY < yB[i])			{				//copy displacement and max				dxB[nextY] = dxB[i];				dyB[nextY] = dyB[i];				yB[nextY] = yB[i];				//Calculate X's				int x_int = xB[i];				int num = xB_num[i] + dxB[i];								if( num >= dyB[i])				{					xB[nextY] = xB[i] + 1;					num = num - dyB[i];				}								xB_num[nextY] = num;			}		}	}	i = 0;	//Fill in Active Edge List	for(i = 0; i < index; i ++)	{		//printf("%d: %d %d\n", i, xA[i], xB[i]);	}	}static void fillPixel(int x, int y){	int x2 = x + 10;	int y2 = y + 10; 	/* draw filled Square */    glBegin(GL_POLYGON);    	glVertex2i(x2*cellSize, y2*cellSize+(cellSize-1));    	glVertex2i(x2*cellSize+(cellSize-1), y2*cellSize+(cellSize-1));   	glVertex2i(x2*cellSize+(cellSize-1), y2*cellSize);	glVertex2i(x2*cellSize, y2*cellSize);    glEnd();}static void changeColor(){	if( colorSwitch == 0)	{		cur_red = 0.0;		cur_green = 1.0;		cur_blue = 0.0;		colorSwitch++;	}	else 	if( colorSwitch == 1)	{		cur_red = 0.0;		cur_green = 0.0;		cur_blue = 1.0;		colorSwitch++;	}	else	if( colorSwitch == 2)	{		cur_red = 1.0;		cur_green = 0.0;		cur_blue = 1.0;		colorSwitch++;	}	else	if( colorSwitch == 3)	{		cur_red = 1.0;		cur_green = 1.0;		cur_blue = 0.0;		colorSwitch++;	}	else	if( colorSwitch == 4)	{		cur_red = 0.0;		cur_green = 1.0;		cur_blue = 1.0;		colorSwitch = 0;	}}/*  /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\   *//*// Function called whenever redisplay needed (try hiding the window and then// exposing it. The debug macro should print something.)*/static void display_CB(void){    glClear(GL_COLOR_BUFFER_BIT);         /* clear the display */	drawGrid();	colorSwitch = 0;	int i = 0;	for( i = 0; i < cmSize; i ++)	{		runCommand(commands[i]);	}	if( first_x != -1)	{		glColor3d(1.0, 0.0, 0.0); 		fillPixel(first_x, first_y);	}	if(polySize == 1)	{		glColor3d(1.0, 0.0, 0.0); 		fillPixel(polyX[0], polyY[0]);	}	for( i = 1; i < polySize; i++)	{		glColor3d(1.0, 0.0, 0.0); 		drawLine(polyX[i-1], polyY[i-1],polyX[i], polyY[i]);	}    glEnd();           /* OpenGL draws the filled triangle */    glFlush();         /* Complete any pending operations */    glutSwapBuffers(); /* Make the drawing buffer the frame buffer                           and vice versa */}/*  /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\   *//* Function called on key press */static void key_CB(unsigned char key, int x, int y) {    	if( key == 'q' ) 	{		saveFile();		exit(0);	}	else if( key == 'u' )	{		cmSize--;		display_CB();		}	else if( key == 'c' ) 	{		cmSize=0;		display_CB();	}	else		display_CB();}/*  /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\   *//* Function called on mouse click */static void mouse_CB(int button, int state, int x, int y)  {    if (button == 0)    {        if (state == 0)        {		display_CB();        }        else if (state == 1)        {		if( mode == 0)		{			glColor3d(1.0, 0.0, 0.0); 			if( first_x == -1)			{				first_x = ((x - (x % cellSize))/cellSize) - 10;				first_y = -(((y - (y % cellSize))/cellSize) - 10);				fillPixel(first_x, first_y);			}			else			{				int sec_x = ((x - (x % cellSize))/cellSize) - 10;				int sec_y = -(((y - (y % cellSize))/cellSize) - 10);				sprintf(commands[cmSize], "line %d %d %d %d\n", first_x, first_y, sec_x, sec_y); 				cmSize++;				first_x = -1;			}					}		else		{			int xTemp = ((x - (x % cellSize))/cellSize) - 10;			int yTemp = -(((y - (y % cellSize))/cellSize) - 10);			if(polySize > 0)			{				if((xTemp == polyX[0]) && (yTemp == polyY[0]))				{					char buff[500];					sprintf(buff, "%s", "poly");					int i = 0;					for(  i = 0; i < polySize; i++)					{						sprintf(buff, "%s %d %d", buff, polyX[i], polyY[i]); 							}					polySize = 0;					sprintf(buff, "%s\n", buff); 					strcpy(commands[cmSize], buff);					cmSize++;				}				else				{					polyX[polySize] = xTemp;					polyY[polySize] = yTemp;					polySize++;				}						}			else			{				polyX[polySize] = xTemp;				polyY[polySize] = yTemp;				polySize++;			}					}				display_CB();        }    }}/*  /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\   */static void add_object_CB(int value){    if (value == DQN_LINE)    {        mode = 0;    }    else if (value == DQN_POLY)    {        mode = 1;    }}