*  main.cpp

 *  CompFormApp




#include <OpenGL/gl.h> //openGL lib

#include <GLUT/glut.h> //glut lib


#include <stdio.h> //input output lib

#include <stdlib.h> //standard lib

#include <math.h> //math lib

#include <time.h>//time lib


#include "shape.h"//shape includes vec2d

#include "grass.h"


int  windowW = 1440; //window Width

int  windowH = 900; //window Height

float     mouseX = windowW/2; //new variable, mouseX

float     mouseY = windowH/2; //mouseY

float     pmouseX=windowW/2;

float     pmouseY=windowH/2;


#define PI 3.14159265358979 //variable for pi


// stuff i use all the time


float radians(float n){


      return n;



float dist(float x, float y, float xx,  float yy){

      float distance;


      return distance;


float constrain(float c, float a, float b){

      if (c<a) c=a;

      if (c>b) c=b;

      else c=c;

      return c;



Vec2d LERP(Vec2d a, Vec2d b, float p){  //(vec, vec, percentage)

      Vec2d c;


      return c;



void drawBezier(Vec2d A, Vec2d B, Vec2d C, Vec2d D){


      for (float p=0;p<1.0;p=p+.1){

            float b=1.0-p;

            Vec2d y=A*b*b*b+B*b*b*p+C*p*p*b+D*p*p*p;






float min (float a, float b){

      if (a<b)

            return a;


            return b;



float max (float a, float b){

      if (a>b)

            return a;


            return b;



int numPoints=0;

Vec2d pointList[1000];



# define nBlades 5000


int randomX[nBlades];

int rows[nBlades];

int randomHeight[nBlades];

float randomWindVelocity[nBlades];

float t[nBlades];

float distance[nBlades];

float angle[nBlades];

float sway[nBlades];

float shiftX[nBlades] ;



void drawBlade( float B1x, float B2x, float B3x, float B4x, int i, int tilt) // variables top x, top-middle x, bottom-middle x, bottom x, i used to control blade arc



      float thickness=randomHeight[i]/5.0;//rows[i]*.4;


      for (int k = 0; k <= thickness; k++ ) { // draw k bezier curves


            Vec2d BezierCurveA(B1x, randomHeight[i]+rows[i]); // top of grass blade; x is random, randomY used for variation in height

            Vec2d BezierCurveB(B2x+(k*0.4),randomHeight[i]*.75+rows[i]); // middle of glass blade, x is random, k widens blade

            Vec2d BezierCurveC(B3x+(k*0.45),randomHeight[i]*.25+rows[i]); // middle of glass blade, x is random, k widens blade

            Vec2d BezierCurveD(B4x+(k*0.3),rows[i]); // bottom of grass blade; x is random, y is fixed, k widens blade towards base


            glBegin (GL_LINE_STRIP);

            for (float p=0; p<=1.0; p+=.125) // creates individual bezier curve



                  float b = 1.0-p;

                  Vec2d CompleteCurve = BezierCurveA*(b*b*b) + BezierCurveB*(3*p*b*b) + BezierCurveC*(3*p*p*b) + BezierCurveD*(p*p*p); // lerp function  


                  float GradientY = b*thickness/20; // gradient along the y axis

                  float nTilt=tilt/100.0*b;


                  if (k < thickness/2) {

                        glColor4f(0.04*k*GradientY+nTilt,.2+0.08*k*GradientY+nTilt,0.008*k*GradientY,.7); // k controls side gradient hue for blade, y controls downward gradient


                  else {

                        glColor4f(0.04*(thickness-k)*GradientY+nTilt,.2+0.08*(thickness-k)*GradientY+nTilt,0.008*(thickness-k)*GradientY,.7); // k controls an opposite side gradient hue for blade, y controls downward gradient



                  glVertex2f (CompleteCurve.x, CompleteCurve.y-75); // offset for grass









void drawField(float x, float y, int i){

      angle[i]=atan2(mouseX-x,mouseY-y); //angle to mouse

      distance[i]=dist(x,y,mouseX,mouseY); //distance to mouse

      float tilt=sin(radians(t[i]))*randomHeight[i]/5;//sway distance

            Vec2d mouse=Vec2d(mouseX,mouseY);


            float brushSize=dist(pmouseX,pmouseY,mouseX,mouseY)+50;


                              if( distance[i]<brushSize){

                                    sway[i]=randomWindVelocity[i]/distance[i]*9*(constrain(angle[i],-2,2));//random velocity * direction in relation to mouse


                              t[i]=t[i]+sway[i]; //sway speed



                              if (t[i]>.1|| t[i]<-.1){





                              drawBlade(randomX[i]+tilt,randomX[i],randomX[i],randomX[i],i,tilt); // variable i used as blade counter and to vary bezier arcs as blade accumulate



shape* myShape;

void displayFunc ( void )


      //first line in displayFunc

      glClearColor(.07,.2,.05,0);//background color


      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //clears screen, color and depth, | binary OR


      //place your drawing code here


                  for (int i = 0; i < nBlades; i++) {




            //myShape->draw(); //-> for pointers



            glutPostRedisplay(); //repeat, redraw

            glutSwapBuffers(); //swaps offscreen buffer, offscreen to onscreen



void reshapeFunc ( int w, int h )


      //windowW = w;  //window width

      //windowH = h; //window height


      windowW = 1440;

      windowH = 900;


      //camera setup

      glViewport( 0, 0, w, h ); //camera view, drawing region (x,y,x,y)

      glMatrixMode( GL_PROJECTION );//camera operations matrix

            glLoadIdentity();//load projection

                  gluOrtho2D( 0,w,0,h ); //set camera to ortho, 2d

                  glMatrixMode( GL_MODELVIEW );//drawing space matrix

                        glLoadIdentity();//load model space




//mouse functions

void mouseDownFunc ( int button, int state, int x, int y )


      mouseX = x;

      mouseY = windowH - y;//y=0 at bottom of screen

                                     //printf("%d %d\n",x,y);//print mouse x,y loc        



void mouseMoveFunc ( int x, int y )//if mouse is moved

{     pmouseX=mouseX;


      mouseX = x;

      mouseY = windowH - y;



void mouseDragFunc ( int x, int y )//if mouse is dragged


      mouseX = x;

      mouseY = windowH - y;








//keyboard functions

void keyboardFunc ( unsigned char key, int x, int y )





void arrowKeyFunc ( int a_keys, int x, int y )





void init ( GLvoid )


      glShadeModel( GL_SMOOTH ); // flat or smooth shading

      glClearColor( 1.0, 1.0, 1.0, 1.0 ); //specify clear values for the color buffers

      glEnable ( GL_COLOR_MATERIAL );//enable server side color material tracking

            glEnable( GL_BLEND );//enable server side blend of rgb values

                  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//specify pixel rgb math



                        //grass init()

                        int i=0;

                        for (int row = 900/*windowH*/+50; row>0; row--) {

                              for (int col=0;col<nBlades/1440/*windowW*/;col++){


                                    randomX[i] = (rand()% 1440/*windowW*/); //top


                                    rows[i] = row;//rand()%windowH;

                              randomHeight[i]=rand() % 60 + 90;//random height from 30 to 80

                              randomWindVelocity[i]=rand() % 15 + 1; //random velocity from 2 to 20










//main function at bottom

int main ( int argc, char** argv )



      glutInit( &argc, argv ); //init GLUT library (& take the address of)


      glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE ); //display mode

      glutInitWindowSize( windowW, windowH ); //initialization of window using window sizes

      glutCreateWindow( "CompFormApp" ); // create a window with name


      //callback functions

      glutDisplayFunc( displayFunc ); //draws window 30fps

      glutReshapeFunc( reshapeFunc ); //resizing window

      glutMouseFunc( mouseDownFunc ); //mousepressed

      glutMotionFunc( mouseDragFunc ); //mousedragged

      glutPassiveMotionFunc( mouseMoveFunc ); //mouseMoved

      glutKeyboardFunc( keyboardFunc ); //keyPressed

      glutSpecialFunc( arrowKeyFunc ); //arrow,shift,etc. keyPressed


      init();//call void init func

            myShape=new shape();






            glutSetCursor( GLUT_CURSOR_NONE );//hides mouse NOT WORKING

            glutMainLoop( );//main event loop, calls custom functions when even occurs


                  return 0; //returns main=0