/*
* 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){
n=n/360*PI*2;
return n;
}
float dist(float x, float y, float xx,
float yy){
float distance;
distance=sqrt((xx-x)*(xx-x)+(yy-y)*(yy-y));
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;
c=a*(1.0-p)+b*p;
return c;
}
void drawBezier(Vec2d A, Vec2d B, Vec2d C, Vec2d
D){
glBegin(GL_LINE_STRIP);
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;
glVertex2f(y.x,y.y);
}
glEnd();
}
float min (float a, float b){
if (a<b)
return a;
else
return b;
}
float max (float a, float b){
if (a>b)
return a;
else
return b;
}
int numPoints=0;
Vec2d pointList[1000];
//grass
# 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
}
glEnd();
}
}
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
//decay
if (t[i]>.1|| t[i]<-.1){
t[i]=t[i]*.999;
}
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++)
{
drawField(randomX[i],rows[i],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;
pmouseY=mouseY;
mouseX
= x;
mouseY
= windowH - y;
}
void mouseDragFunc ( int x, int y )//if mouse is dragged
{
mouseX
= x;
mouseY
= windowH - y;
if(numPoints<1000){
pointList[numPoints].x=mouseX;
pointList[numPoints].y=mouseY;
numPoints++;
}
}
//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
i++;
}
}
}
//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();
myShape->addPoint(Vec2d(100,100));
myShape->addPoint(Vec2d(400,400));
myShape->addPoint(Vec2d(100,300));
glutFullScreen();//fullscreen
glutSetCursor(
GLUT_CURSOR_NONE );//hides mouse NOT WORKING
glutMainLoop(
);//main
event loop, calls custom functions when even occurs
return 0; //returns main=0
}