1: /* File: dmcgl.c
     2:    Submitted as part of Project 4 for EECS 672, Spring 2007
     3:    by Douglas McClendon, KUID 0536810
     4: */
     5: 
     6: 
     7: #include "dmcgl.h" 
     8: 
     9: void stretch(double *x, double *y, double *z, double r)
    10: {
    11: 	double length;
    12: 
    13: 	length = vector_length(*x,*y,*z);
    14: 	(*x)=(*x)/length*r;
    15: 	(*y)=(*y)/length*r;
    16: 	(*z)=(*z)/length*r;
    17: }
    18: 
    19: void save_buffer_to_ppm(unsigned char *buffer, int width, int height,\
    20: 				 char *filename) 
    21: {
    22:     /*
    23:     This function saves the contents of the global frame buffer to a
    24:     ppm file of the given name.  This function is dependent on the 
    25: 	global _buffer_ array.
    26:     */
    27: 
    28:     FILE *f;
    29:     
    30:     f = fopen( filename, "w" );
    31:     if (f) {
    32:         int i, x, y;
    33: 	
    34: 		fprintf(f,"P6\n");
    35: 		fprintf(f,"# ppm-file\n");
    36: 		fprintf(f,"%i %i\n", width, height);
    37: 		fprintf(f,"255\n");
    38: 		fclose(f);
    39: 		f = fopen( filename, "ab" );  /* reopen in binary append mode */
    40: 		for (y=height-1; y>=0; y--) {
    41: 			for (x=0; x<width; x++) {
    42: 				i = (y*width + x) * 4;
    43: 				fputc(buffer[i], f);   /* write red */
    44: 				fputc(buffer[i+1], f); /* write green */
    45: 				fputc(buffer[i+2], f); /* write blue */
    46: 			}
    47: 		}
    48: 		fclose(f);
    49:     }
    50: }
    51: 
    52: 
    53: int read_ppm_to_buffer(unsigned char **buffer, int *width, int *height,\
    54: 					   const char *filename)
    55: {
    56: 	
    57:     FILE *f;
    58:     
    59:     f = fopen( filename, "r" );
    60:     if (f) {
    61:         int i, x, y;
    62: 		char *temp;
    63: 
    64: 
    65: 		fscanf(f,"P6\n");
    66: 		temp=(char *)malloc(255);
    67: 		fgets(temp,255,f);
    68: 		free(temp);
    69: 		fscanf(f,"%i %i\n", width, height);
    70: 		fscanf(f,"255\n");
    71: 		
    72: 		*buffer=(unsigned char *)malloc((*width)*(*height)*4);
    73: 		if(*buffer==NULL){
    74: 			fprintf(stderr,"read_buffer_to_ppm failed on malloc\n");
    75: 			fflush(stderr);
    76: 			exit(1);
    77: 		}
    78: 		
    79: 		for (y=(*height)-1; y>=0; y--) {
    80: 			for (x=0; x<(*width); x++) {
    81: 				i = (y*(*width) + x) * 4;
    82: 				(*buffer)[i]=fgetc(f);
    83: 				(*buffer)[i+1]=fgetc(f);
    84: 				(*buffer)[i+2]=fgetc(f);
    85: 			}
    86: 		}
    87: 		fclose(f);
    88: 		return(1);
    89:     } else return(0);
    90: } 
    91: 
    92: int generate_checkerboard_texture(unsigned char **buffer, int *width, int *height)
    93: {
    94:   int i = 0;
    95:   *width = 2;
    96:   *height = 2;
    97:   
    98:   *buffer=(unsigned char *)malloc((*width)*(*height)*4);
    99:   if(*buffer==NULL){
   100:     fprintf(stderr,"read_buffer_to_ppm failed on malloc\n");
   101:     fflush(stderr);
   102:     exit(1);
   103:   }
   104: 
   105:   (*buffer)[i++] = 255;
   106:   (*buffer)[i++] = 0;
   107:   (*buffer)[i++] = 0;
   108:   (*buffer)[i++] = 0;
   109: 
   110:   (*buffer)[i++] = 0;
   111:   (*buffer)[i++] = 255;
   112:   (*buffer)[i++] = 0;
   113:   (*buffer)[i++] = 0;
   114: 
   115:   (*buffer)[i++] = 0;
   116:   (*buffer)[i++] = 0;
   117:   (*buffer)[i++] = 255;
   118:   (*buffer)[i++] = 0
   119:     ;
   120: 
   121:   (*buffer)[i++] = 255;
   122:   (*buffer)[i++] = 255;
   123:   (*buffer)[i++] = 255;
   124:   (*buffer)[i++] = 0;
   125: 
   126: }
   127: 
   128: void xyz2rtp(double *r, double *t, double *p, double x, double y, double z)
   129: {
   130: 	*r=vector_length(x,y,z);
   131: 	*p=asin(z/(*r));
   132: 	*t=atan2(y,x);
   133: }
   134: 
   135: void rtp2xyz(double *x, double *y, double *z, double r, double t, double p)
   136: {
   137: 
   138: 	*z=sin(p)*r;
   139: 	/*
   140: 	*x=sqrt((r*r*(1-sin(p)*sin(p)))/(1+tjan(t)*tan(t)));
   141: 	*y=tan(t)*(*x);
   142: 	*/
   143: 	*x=cos(t)*cos(p)*r;
   144: 	*y=sin(t)*cos(p)*r;
   145: 
   146: 
   147: }
   148: 
   149: 
   150: 
   151: double vector_length(double x, double y, double z)
   152: {
   153: 	return(sqrt(x*x+y*y+z*z));
   154: }
   155: 
   156: void rand_vector(double *x, double *y, double *z)
   157: {
   158: 	int done;
   159: 	
   160: 	done=0;
   161: 	while(!done){
   162: 		*x=randfn1();
   163: 		*y=randfn1();
   164: 		*z=randfn1();
   165: 		if(vector_length(*x,*y,*z)<=1) done=1;
   166: 	}
   167: }
   168: 
   169: void draw_line_cube(double r)
   170: {
   171: 	glPushMatrix();
   172: 
   173: 	glColor3f(1,1,1);
   174: 
   175: 	glBegin(GL_LINES);
   176: 	    glVertex3f(r,r,r);
   177:        	    glVertex3f(r,r,-r);
   178: 	glEnd();
   179: 	glBegin(GL_LINES);
   180: 	    glVertex3f(r,r,r);
   181: 		glVertex3f(r,-r,r);
   182: 	glEnd();
   183: 	glBegin(GL_LINES);
   184: 	    glVertex3f(r,r,r);
   185: 		glVertex3f(-r,r,r);
   186: 	glEnd();
   187: 	glBegin(GL_LINES);
   188: 	    glVertex3f(-r,-r,-r);
   189: 	    glVertex3f(-r,-r,r);
   190: 	glEnd();
   191: 	glBegin(GL_LINES);
   192: 	    glVertex3f(-r,-r,-r);
   193: 	    glVertex3f(-r,r,-r);
   194: 	glEnd();
   195: 	glBegin(GL_LINES);
   196: 	    glVertex3f(-r,-r,-r);
   197: 	    glVertex3f(r,-r,-r);
   198: 	glEnd();
   199: 	glBegin(GL_LINES);
   200: 	    glVertex3f(-r,-r,r);
   201: 		glVertex3f(r,-r,r);
   202: 	glEnd();
   203: 	glBegin(GL_LINES);
   204: 	    glVertex3f(-r,-r,r);
   205: 		glVertex3f(-r,r,r);
   206: 	glEnd();
   207: 	glBegin(GL_LINES);
   208: 	    glVertex3f(r,r,-r);
   209: 		glVertex3f(-r,r,-r);
   210: 	glEnd();
   211: 	glBegin(GL_LINES);
   212: 	    glVertex3f(r,r,-r);
   213: 		glVertex3f(r,-r,-r);
   214: 	glEnd();
   215: 	glBegin(GL_LINES);
   216: 	    glVertex3f(-r,r,-r);
   217: 		glVertex3f(-r,r,r);
   218: 	glEnd();
   219: 	glBegin(GL_LINES);
   220: 	    glVertex3f(r,-r,-r);
   221: 		glVertex3f(r,-r,r);
   222: 	glEnd();
   223: 
   224: 
   225: 	glPopMatrix();
   226: }
   227: 
   228: void draw_diamond()
   229: {
   230: 	GLfloat va[3]={0.0,+1.0,0.0};
   231: 	GLfloat vb[3]={-1.0,0.0,0.0};
   232: 	GLfloat vc[3]={0.0,0.0,-1.0};
   233: 	GLfloat vd[3]={+1.0,0.0,0.0};
   234: 	GLfloat ve[3]={0.0,0.0,+1.0};
   235: 	GLfloat vf[3]={0.0,-1.0,0.0};
   236: 
   237: 	glEnable(GL_COLOR_MATERIAL);
   238: 
   239: 	/* face a b c */
   240: 	glColor3f(1, 0, 0);
   241: 	glBegin(GL_POLYGON);
   242: 		glNormal3fv(va);
   243: 	 	glVertex3fv(va);
   244: 		glNormal3fv(vb);
   245: 	 	glVertex3fv(vb);
   246: 		glNormal3fv(vc);
   247:   	 	glVertex3fv(vc);
   248: 	glEnd();
   249: 	/* face a d c */
   250: 	glColor3f(0, 1, 0);
   251: 	glBegin(GL_POLYGON);
   252: 		glNormal3fv(va);
   253: 	 	glVertex3fv(va);
   254: 		glNormal3fv(vd);
   255: 	 	glVertex3fv(vd);
   256: 		glNormal3fv(vc);
   257:   	 	glVertex3fv(vc);
   258: 	glEnd();
   259: 	/* face a b e */
   260: 	glColor3f(0, 0, 1);
   261: 	glBegin(GL_POLYGON);
   262: 		glNormal3fv(va);
   263: 	 	glVertex3fv(va);
   264: 		glNormal3fv(vb);
   265: 	 	glVertex3fv(vb);
   266: 		glNormal3fv(ve);
   267:   	 	glVertex3fv(ve);
   268: 	glEnd();
   269: 	/* face a d e */
   270: 	glColor3f(1, 0, 1);
   271: 	glBegin(GL_POLYGON);
   272: 		glNormal3fv(va);
   273: 	 	glVertex3fv(va);
   274: 		glNormal3fv(vd);
   275: 	 	glVertex3fv(vd);
   276: 		glNormal3fv(ve);
   277:   	 	glVertex3fv(ve);
   278: 	glEnd();
   279: 	/* face f b c */
   280: 	glColor3f(1, 0, 0);
   281: 	glBegin(GL_POLYGON);
   282: 		glNormal3fv(vf);
   283: 	 	glVertex3fv(vf);
   284: 		glNormal3fv(vb);
   285: 	 	glVertex3fv(vb);
   286: 		glNormal3fv(vc);
   287:   	 	glVertex3fv(vc);
   288: 	glEnd();
   289: 	/* face f d c */
   290: 	glColor3f(0, 1, 0);
   291: 	glBegin(GL_POLYGON);
   292: 		glNormal3fv(vf);
   293: 	 	glVertex3fv(vf);
   294: 		glNormal3fv(vd);
   295: 	 	glVertex3fv(vd);
   296: 		glNormal3fv(vc);
   297:   	 	glVertex3fv(vc);
   298: 	glEnd();
   299: 	/* face f b e */
   300: 	glColor3f(0, 0, 1);
   301: 	glBegin(GL_POLYGON);
   302: 		glNormal3fv(vf);
   303: 	 	glVertex3fv(vf);
   304: 		glNormal3fv(vb);
   305: 	 	glVertex3fv(vb);
   306: 		glNormal3fv(ve);
   307:   	 	glVertex3fv(ve);
   308: 	glEnd();
   309: 	/* face f d e */
   310: 	glColor3f(1, 0, 1);
   311: 	glBegin(GL_POLYGON);
   312: 		glNormal3fv(vf);
   313: 	 	glVertex3fv(vf);
   314: 		glNormal3fv(vd);
   315: 	 	glVertex3fv(vd);
   316: 		glNormal3fv(ve);
   317:   	 	glVertex3fv(ve);
   318: 	glEnd();
   319: 
   320: 	glDisable(GL_COLOR_MATERIAL);
   321: }
   322: 
   323: void fbnSolidTexturedCube(double size)
   324: {
   325:   static GLfloat n[6][3] =
   326:   {
   327:     {-1.0, 0.0, 0.0},
   328:     {0.0, 1.0, 0.0},
   329:     {1.0, 0.0, 0.0},
   330:     {0.0, -1.0, 0.0},
   331:     {0.0, 0.0, 1.0},
   332:     {0.0, 0.0, -1.0}
   333:   };
   334:   static GLint faces[6][4] =
   335:   {
   336:     {0, 1, 2, 3},
   337:     {3, 2, 6, 7},
   338:     {7, 6, 5, 4},
   339:     {4, 5, 1, 0},
   340:     {5, 6, 2, 1},
   341:     {7, 4, 0, 3}
   342:   };
   343:   GLfloat v[8][3];
   344:   GLint i;
   345: 
   346:   v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
   347:   v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
   348:   v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
   349:   v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
   350:   v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
   351:   v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
   352: 
   353:   for (i = 5; i >= 0; i--) {
   354:     glBegin(GL_QUADS);
   355:     glNormal3fv(&n[i][0]);
   356:     glTexCoord2f(1.0, 0.0);
   357:     glVertex3fv(&v[faces[i][0]][0]);
   358:     glTexCoord2f(0.0, 0.0);
   359:     glVertex3fv(&v[faces[i][1]][0]);
   360:     glTexCoord2f(0.0, 1.0);
   361:     glVertex3fv(&v[faces[i][2]][0]);
   362:     glTexCoord2f(1.0, 1.0);
   363:     glVertex3fv(&v[faces[i][3]][0]);
   364:     glEnd();
   365:   }
   366: }
   367: 
   368: void copy_vertex(GLfloat *dest, GLfloat *src)
   369: {
   370: 	dest[0]=src[0];
   371: 	dest[1]=src[1];
   372: 	dest[2]=src[2];
   373: }
   374: 
   375: void set_vertex(GLfloat *dest, GLfloat x, GLfloat y, GLfloat z)
   376: {
   377: 	dest[0]=x;
   378: 	dest[1]=y;
   379: 	dest[2]=z;
   380: }
   381: 
   382: float randf01()
   383: {
   384: 	return((float)(rand()/(RAND_MAX+1.0)));
   385: }
   386: 
   387: float randfn1()
   388: {
   389: 	return(2*((float)(rand()/(RAND_MAX+1.0)))-1);
   390: }
   391: 
   392: