/* * use the de Casteljau algorithm to subdivide the Bezier surface divisions times, * then draw either the lines connecting the control points, if solid is 0, * or draw triangles connecting the surface. */ void module_bezierSurface(Module *m, BezierSurface *b, int divisions, int solid){ int i, j, k, l; Line tempLine; Point grid[7][7]; Point controls[7]; Point deCast[7]; Point surfacePoints[16]; BezierSurface tempBezSurf; Polygon *temptri = polygon_create(); if(!m || !b){ printf("Null passed to module_bezierSurface\n"); return; } // base case if(divisions == 0){ // lines if(solid == 0){ for(i=0;i<4;i++){ for(j=0;j<3;j++){ line_set(&tempLine, b->c[i][j], b->c[i][j+1]); module_line(m, &tempLine); line_set(&tempLine, b->c[j][i], b->c[j+1][i]); module_line(m, &tempLine); } } } // triangles else { controls[0] = b->c[0][0]; controls[1] = b->c[0][3]; controls[2] = b->c[3][3]; controls[3] = b->c[3][0]; controls[4] = b->c[0][0]; polygon_set(temptri, 3, &(controls[0])); module_polygon(m, temptri); polygon_set(temptri, 3, &(controls[2])); module_polygon(m, temptri); } } // divide and recurse else { // compute all avg points for 3 orders, down to just one point 3rd order // do for each of the four bezier curves for(i=0;i<4;i++){ deCasteljau(&(deCast[0]), &(b->c[i][0])); for(j=0;j<7;j++){ grid[2*i][j] = deCast[j]; } } // now traverse the other direction, populating grid for(i=0;i<7;i++){ for(j=0;j<4;j++){ controls[j] = grid[2*j][i]; } deCasteljau(&(deCast[0]), &(controls[0])); for(j=0;j<7;j++){ grid[j][i] = deCast[j]; } } // now make the four new bezier surfaces by subdividing across for(i=0;i<2;i++){ for(j=0;j<2;j++){ for(k=0;k<4;k++){ for(l=0;l<4;l++){ surfacePoints[4*k+l] = grid[k+3*i][l+3*j]; } } bezierSurface_set(&tempBezSurf, &(surfacePoints[0])); // recursive call module_bezierSurface(m, &tempBezSurf, divisions-1, solid); } } } // clean up polygon_free(temptri); }
// makes 3 X-wing fighters in a loose formation int main(int argc, char *argv[]) { int i, j; //loop variables Image *src; Module* wall; Module* ray; Module* ray2; Module *scene1; Module* scene2; Polygon p; Line l; Point point[4]; Point point2[2]; View3D view; Matrix vtm, gtm; DrawState *ds; char filename[100]; Color Flame = { { 1.0, 0.7, 0.2 } }; Color Red = { { 1.0, 0.2, 0.1 } }; Color Grey = { { 0.745, 0.745, 0.745} }; Color Blue = {{0.117647, 0.564706, 1}}; // Color Grey = {{1, 1, 1}}; // set up the view point_set3D( &(view.vrp), 4, 4, 4 ); vector_set( &(view.vpn), -view.vrp.val[0], -view.vrp.val[1], -view.vrp.val[2] ); vector_set( &(view.vup), 0, 1, 0 ); view.d = 1; view.du = 1.6; view.dv = 0.9; view.f = 1; view.b = 50; view.screenx = 640; view.screeny = 360; matrix_setView3D( &vtm, &view ); matrix_identity( >m ); // //wall wall = module_create(); module_color(wall, &Red); polygon_init(&p); point_set3D(&point[0], 1,1,2); point_set3D(&point[1], 1,0,2); point_set3D(&point[2], 0,0,2); point_set3D(&point[3], 0,1,2); polygon_set(&p, 4, &point[0]); module_polygon(wall, &p); //ray ray = module_create(); module_color(ray, &Blue); for(i=0; i< 5; i++){ point_set3D(&point2[0], -1+0.01*i, -1, 1); point_set3D(&point2[1], 1+0.01*i, 1, 1); line_set(&l, point2[0], point2[1]); module_line(ray, &l); } //ray2 ray2 = module_create(); module_color(ray2, &Red); for(i=0; i< 5; i++){ point_set3D(&point2[0], -1+0.01*i, 1, -1); point_set3D(&point2[1], 1+0.01*i, -1, -1); line_set(&l, point2[0], point2[1]); // line_zBuffer(&l, 0); module_line(ray2, &l); } //scene // scene = module_create(); // module_module(scene, wall); // module_module(scene, ray); // module_module(scene, ray2); // module_module(scene, wall); for(i=0; i< 36; i++){ //scene scene1 = module_create(); scene2 = module_create(); module_rotateZ(scene1, cos(i*10 * M_PI/180), sin(i*10 * M_PI/180)); module_scale( scene1, 3, 1, 2 ); module_color( scene1, &Blue ); module_cube( scene1, 1); module_scale(scene2, 0.5, 0.5, 0.5); module_cylinder(scene2, 30); // create the image and drawstate src = image_create( 360, 640 ); ds = drawstate_create(); drawstate_setAlpha(ds, 1); ds->shade = ShadeDepth; // draw into the scene // module_draw( scene1, &vtm, >m, ds, src ); drawstate_setAlpha(ds, 1 ); module_draw( scene1, &vtm, >m, ds, src ); // write out the scene sprintf(filename, "frame_%.2d.ppm", i); image_write( src, filename ); module_delete( scene1); } //free the polygon data // polygon_clear( &p ); // free the modules // module_delete( scene); // module_delete( wall ); // free the drawstate free(ds); // free the image image_free( src ); return(0); }