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();
}