Fall
//John Lynch, Betsy Savare, Akemi Shinkai //Fractal Seasons /**************************************include files*****************************************/ #include<windows.h> #include<glut.h> #include<cstdlib> //#include<iostream.h> #include<time.h> #include<math.h> #define NUM_TREES 20 #define NUM_LEAVES 2881 //144 leaves per tree + one more #define LEAFSIZE 8 /**************************************global constants*****************************************/ //change these values for differnt screens sizes const int screenWidth = 640; const int screenHeight = 480; const int outerdelay = 1000; const int innerdelay = 1000000; /**************************************data structures*****************************************/ class Point2{ public: Point2 () {x = y = 0.0f;} Point2 (float xx, float yy) {x = xx; y = yy;} void set(float xx, float yy) {x = xx; y = yy;} float getX() {return x;} float getY() {return y;} float x, y; private: }; //Point2 class Leaf{ public: Leaf() {angle = 0;} void drawLeaf(); Point2 getStart() {return startpoint;} Point2 getEnd() {return endpoint;} Point2 startpoint; Point2 endpoint; float angle; float width; float dropped; float c1; float c2; float c3; private: }; //leaf void Leaf:: drawLeaf(){ float x1, y1, x2, y2; x1 = startpoint.getX(); y1 = startpoint.getY(); x2 = endpoint.getX(); y2 = endpoint.getY(); glLineWidth(width); glBegin (GL_LINES); glVertex2f ((GLfloat)x1, (GLfloat)y1); glVertex2f ((GLfloat)x2, (GLfloat)y2); glEnd(); } //drawleaf struct Node{ Point2 x; float angle; Node *next; }; //Node typedef struct Node NodeType; class Stack{ public: Stack() {head_ptr = NULL;} void addToStack(Point2 x, float angle); Node retrieveFromStack(); private: Node *head_ptr; }; //stack class Canvas{ public: Canvas(); Canvas(Point2 p, float angle); void turnTo(float angle) {CD+=angle;} void lineTo(float x, float y); void lineTo(Point2 P); void forward(float dist, int isVisible); void backward(float dist, int isVisible); void moveTo(float x, float y); void moveTo(Point2 P); void savePosition(); void retrievePosition(); void reset_idx() {idx = 0;} Point2 getPosition() {return CP;} float getDirection() {return CD;} private: Point2 CP; float CD; int idx; Stack stack; NodeType one_node; }; //canvas void Stack:: addToStack(Point2 xx, float aangle){ NodeType *insert_ptr; insert_ptr = new Node; insert_ptr->x = xx; insert_ptr->angle = aangle; insert_ptr->next = head_ptr; head_ptr = insert_ptr; } //addToStack NodeType Stack:: retrieveFromStack(){ NodeType *temp_ptr; NodeType saved_values; temp_ptr = head_ptr; saved_values.x = temp_ptr->x; saved_values.angle = temp_ptr->angle; head_ptr = head_ptr->next; free(temp_ptr); return saved_values; } //rettrieveFromStack Canvas:: Canvas(Point2 p, float angle){ float x = p.getX(); float y = p.getY(); CP.set(x, y); CD = angle; reset_idx(); } //canvas void Canvas:: lineTo(float x, float y){ glBegin (GL_LINES); glVertex2f ((GLfloat)CP.x, (GLfloat)CP.y); glVertex2f ((GLfloat) x, (GLfloat) y); glEnd(); CP.set (x,y); //glFlush(); } //lineTo void Canvas:: moveTo(float x, float y){ CP.set(x, y); } //moveTo void Canvas:: forward(float dist, int isVisible){ const float RadPerDeg=0.017453393; float x = CP.x + dist * cos(RadPerDeg * CD); float y = CP.y + dist * sin(RadPerDeg * CD); if(isVisible) lineTo(x, y); else moveTo(x, y); CP.set(x, y); } //forward void Canvas:: backward(float dist, int isVisible){ const float RadPerDeg=0.017453393; float x = CP.x - dist * cos(RadPerDeg * CD); float y = CP.y - dist * sin(RadPerDeg * CD); if(isVisible) lineTo(x, y); else moveTo(x, y); CP.set(x, y); } //backward void Canvas:: savePosition(){ stack.addToStack(CP, CD); } //savePosition void Canvas:: retrievePosition(){ one_node = stack.retrieveFromStack(); CP = one_node.x; CD = one_node.angle; } //retrievePosition int ctr = 0; // array to hold leaves Leaf each_leaf[NUM_LEAVES]; Point2 each_tree[NUM_TREES+1]; void drawBranch(Canvas &turtle, float scale){ Leaf leaf; glLineWidth(2.5); //set line width to 2.5 pixels glColor3f(0.65f, 0.16f, 0.16f); //brown turtle.forward(scale * LEAFSIZE, 1); //first part of the branch turtle.turnTo(-15); leaf.startpoint = turtle.getPosition(); leaf.angle = turtle.getDirection(); glColor3f(1.0f, 1.0f, 1.0f); //white glLineWidth(6.0); turtle.forward(scale * LEAFSIZE, 1); //first leaf leaf.endpoint = turtle.getPosition(); leaf.width = 6.0; leaf.dropped = 0; ctr++; each_leaf[ctr] = leaf; glLineWidth(2.5); turtle.backward(scale * LEAFSIZE, 0); turtle.turnTo(+15); glLineWidth(2.0); //set line width to 2.0 pixels glColor3f(0.65f, 0.16f, 0.16f); //brown turtle.forward(scale * LEAFSIZE, 1); //second part of the branch turtle.turnTo(+15); leaf.startpoint = turtle.getPosition(); leaf.angle = turtle.getDirection(); glColor3f(1.0f, 1.0f, 1.0f); //white glLineWidth(6.0); turtle.forward(scale * LEAFSIZE, 1); //second leaf leaf.endpoint = turtle.getPosition(); leaf.width = 6.0; leaf.dropped = 0; ctr++; each_leaf[ctr] = leaf; glLineWidth(2.0); turtle.backward(scale * LEAFSIZE, 0); turtle.turnTo(-15); glLineWidth(1.5); //set line width to 1.5 pixels glColor3f(0.65f, 0.16f, 0.16f); //brown turtle.forward(scale * LEAFSIZE, 1); //third part of the branch turtle.turnTo(-15); leaf.startpoint = turtle.getPosition(); leaf.angle = turtle.getDirection(); glColor3f(1.0f, 1.0f, 1.0f); //white glLineWidth(6.0); turtle.forward(scale * LEAFSIZE, 1); //third leaf leaf.endpoint = turtle.getPosition(); leaf.width = 6.0; leaf.dropped = 0; ctr++; each_leaf[ctr] = leaf; glLineWidth(1.5); turtle.backward(scale * LEAFSIZE, 0); turtle.turnTo(+15); glLineWidth(1.0); //set line width to 1.0 pixels glColor3f(0.65f, 0.16f, 0.16f); //brown turtle.forward(scale * LEAFSIZE, 1); //fourth part of branch turtle.turnTo(+15); leaf.startpoint = turtle.getPosition(); leaf.angle = turtle.getDirection(); glColor3f(1.0f, 1.0f, 1.0f); //white glLineWidth(6.0); turtle.forward(scale * LEAFSIZE, 1); //fourth leaf leaf.endpoint = turtle.getPosition(); leaf.width = 6.0; leaf.dropped = 0; ctr++; each_leaf[ctr] = leaf; glLineWidth(1.0); glColor3f(0.65f, 0.16f, 0.16f); //brown turtle.backward(scale * LEAFSIZE, 0); turtle.turnTo(-15); } void Branch(Point2 p, float angle, float scale, float level){ Canvas turtle(p, angle); glLineWidth(3.5); //set line width to 3.5 pixels turtle.forward(scale * 2 * LEAFSIZE, 1); //trunk turtle.turnTo(-22); turtle.savePosition(); turtle.turnTo(-22); if(level==0){ drawBranch(turtle, scale); } else Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1); turtle.turnTo(+22); if(level==0){ drawBranch(turtle, scale); } else Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1); turtle.turnTo(+22); if(level==0){ drawBranch(turtle, scale); } else Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1); turtle.retrievePosition(); turtle.turnTo(+22); turtle.savePosition(); turtle.turnTo(+22); if(level==0){ drawBranch(turtle, scale); } else Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1); turtle.turnTo(-22); if(level==0){ drawBranch(turtle, scale); } else Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1); turtle.turnTo(-22); if(level==0){ drawBranch(turtle, scale); } else Branch(turtle.getPosition(), turtle.getDirection(), scale, level - 1); turtle.retrievePosition(); } /********************makeBackground*************************************************/ /* this function draws a dark green rectangle to represent the ground then uses nested for loops to traverse the screen drawing grass it the draws a blue rectangle a the upper 1/3 of the screen to represent the sky */ void makeBackground(void) { glColor3f(0.0,0.0,0.2); glRecti(0,0,screenWidth,2*screenHeight/3); for(int f=1; f < screenWidth; f=f+4) { for(int g=1; g < screenHeight; g=g+4) { int color = rand()%3; switch(color){ case 0: glColor3f(0.0f, 0.7f, 0.0f); //light green break; case 1: glColor3f(0.0f, 0.5f, 0.0f); //dark green break; case 2: glColor3f(0.0f, 0.3f, 0.0f); //darker still break; }//switch glLineWidth(1.0); //draw a blade glBegin(GL_LINES); glVertex2i(f, g); glVertex2i(f+ (rand()%10), g+5); glEnd(); }//for }//for //added rectangle //this draws in a rectangle to represent the sky //if you want clouds put your bmp code here glColor3f(0.0,0.0,0.6); glRecti(0,screenHeight,screenWidth, screenHeight-screenHeight/3); }//makeBackground void spring(void){ //*******randomly turn the leaves green***Spring glLineWidth(6.0); //set line width to 6 pixels glColor3f(0.0f, 0.7f, 0.0f); //green for(int i = 1; i < NUM_LEAVES; i++){ ctr = (rand()%NUM_LEAVES) +1; if(ctr > NUM_LEAVES) ctr = NUM_LEAVES; each_leaf[ctr].drawLeaf(); for(float j = 0; j < 300000; j++); //delay loop //added glflush glFlush(); } } //spring //*******turn all of the leaves green*****Summer void summer(void){ glLineWidth(6.0); //set line width to 6 pixels glColor3f(0.0f, 0.5f, 0.0f); //green ctr = 0; for(int i = 1; i <= NUM_LEAVES; i++){ ctr++; each_leaf[ctr].drawLeaf(); for(float j = 0; j < 50000; j++); //delay loop //added glflush glFlush(); } } //summer void fall(void){ //*******turn all of the leaves red, yellow or orange**Fall int color; glLineWidth(6.0); //set line width to 6 pixels for(int i = 0; i <= NUM_LEAVES; i++){ color = rand()%3; switch(color){ case 0: glColor3f(1.0f, 0.0f, 0.0f); //red each_leaf[i].c1 = 1.0; each_leaf[i].c2 = 0.0; each_leaf[i].c3 = 0.0; break; case 1: glColor3f(1.0f, 0.65f, 0.0f); //orange each_leaf[i].c1 = 1.0; each_leaf[i].c2 = 0.65; each_leaf[i].c3 = 0.0; break; case 2: glColor3f(1.0f, 1.0f, 0.0f); //yellow each_leaf[i].c1 = 1.0; each_leaf[i].c2 = 1.0; each_leaf[i].c3 = 0.0; break; } each_leaf[i].drawLeaf(); //added glflush glFlush(); for(float j = 0; j < 50000; j++); //delay loop } float drop_point = screenHeight/6 - 50; float bottom = screenHeight - 10; Point2 start; Point2 end; float x1, y1, x2, y2; int odd_even; Leaf leaf; for(int a = 0; a< 1000; a++); //delay loop for(int i = 1; i <= NUM_LEAVES; i++){ ctr = (rand()%NUM_LEAVES) +1; if(ctr > NUM_LEAVES) ctr = NUM_LEAVES; leaf = each_leaf[ctr]; start = leaf.getStart(); end = leaf.getEnd(); x1 = start.getX(); y1 = start.getY(); x2 = end.getX(); y2 = end.getY(); glColor3f(1.0f, 1.0f, 1.0f); //white each_leaf[ctr].drawLeaf(); glColor3f(leaf.c1, leaf.c2, leaf.c3); if(ctr%2==0) odd_even = ctr*5; else odd_even = ctr*3; if(leaf.dropped == 0){ y1 = drop_point+rand()%odd_even; Point2 new_start(x1, y1); Canvas turtle(new_start, leaf.angle); turtle.forward(LEAFSIZE, 1); leaf.startpoint = new_start; leaf.endpoint = turtle.getPosition(); leaf.dropped = 1; each_leaf[ctr]= leaf; } else if(leaf.dropped == 1); else{ y1 = y1 - 60+ rand()%50; Point2 new_start(x1, y1); Canvas turtle(new_start, leaf.angle); turtle.forward(LEAFSIZE, 1); leaf.startpoint = new_start; leaf.endpoint = turtle.getPosition(); leaf.dropped++; each_leaf[ctr]= leaf; } for( int a = 0; a< 100000; a++); } ctr = 0; glColor3f(0.65f, 0.16f, 0.16f); //set drawing color to brown int tree_ctr = 0; int x = (NUM_TREES / 3) + 3; int y = (NUM_TREES / 3) + 0; int z = (NUM_TREES / 3) - 3; for(int i = 1; i <= x; i++){ tree_ctr++; Point2 init = each_tree[tree_ctr]; int xx = init.getX(); int yy = init.getY(); Branch(init, 90, 1.5, 1); //init point, angle, scale, levels } for(int i = 1; i <= y; i++){ tree_ctr++; Point2 init = each_tree[tree_ctr]; int xx = init.getX(); int yy = init.getY(); Branch(init, 90, 2.5, 1); } for(int i = 1; i <= z; i++){ tree_ctr++; Point2 init = each_tree[tree_ctr]; int xx = init.getX(); int yy = init.getY(); Branch(init, 90, 3, 1); } //added glflush glFlush(); }//fall void Br(void) { glClear(GL_COLOR_BUFFER_BIT); //*******draw trees**********************Winter int i; int x, y, z; int tree_ctr = 0; float xx, yy; x = (NUM_TREES / 3) + 3; y = (NUM_TREES / 3) + 0; z = (NUM_TREES / 3) - 3; //put in grass and sky makeBackground(); for(i = 1; i <= x; i++){ tree_ctr++; Point2 init(rand()%25 + (i * screenWidth / (x + 3)), (3*screenHeight/4.5) + rand()%40); each_tree[tree_ctr] = init; xx = init.getX(); yy = init.getY(); Branch(init, 90, 1.5, 1); //init point, angle, scale, levels } for(i = 1; i <= y; i++){ tree_ctr++; Point2 init(rand()%40+ (i * screenWidth / (y + 3)), (2*screenHeight/5) + rand()%40); each_tree[tree_ctr] = init; xx = init.getX(); yy = init.getY(); Branch(init, 90, 2.5, 1); } for(i = 1; i <= z; i++){ tree_ctr++; Point2 init(rand()%40 + (i * screenWidth / (z + 3)), (1*screenHeight/6) + rand()%60); each_tree[tree_ctr] = init; xx = init.getX(); yy = init.getY(); Branch(init, 90, 3, 1); } //added glflush glFlush(); //spring call spring(); //delay between seasons for(int a = 0; a< innerdelay; a++){ for (int b = 0; b < outerdelay; b++); } //summer call summer(); //delay between seasons for(int a = 0; a< innerdelay; a++){ for (int b = 0; b < outerdelay; b++); } //call fall fall(); } //br void myInit(void) { glClearColor(1.0,1.0,1.0,0.0); //set background color. glColor3f(0.65f, 0.16f, 0.16f); //set drawing color to brown glLineWidth(3.0); //set line width to 3 pixels glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble)screenWidth, 0.0, (GLdouble)screenHeight); } void main(int argc, char** argv) { glutInit(&argc, argv); //initialize the toolkit glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//set display mode glutInitWindowSize(screenWidth, screenHeight); //setwindowsize glutInitWindowPosition(100,100); //set window position on screen glutCreateWindow("This is a Tree"); //open the screen window glutDisplayFunc(Br); //register redraw function myInit(); glutMainLoop(); }