Grass: Brush

wk6grassscreenshot_1.png
A small step towards realistic grass in openGL and C. Grass responds to “petting” via mouse control.

//grass
# define nBlades 30000

int randomX[nBlades];
int randomY[nBlades];
int randomHeight[nBlades];
float randomWindVelocity[nBlades];
float t[nBlades];
float distance[nBlades];
float angle[nBlades];
float sway[nBlades];
float	pmouseX=0;
float	pmouseY=0;
void drawBlade2(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);
		Vec2d A=Vec2d(x,y);//grass root
			Vec2d B=Vec2d(x*3,y*3+randomHeight[i]*.1);//first control point 
				Vec2d C=Vec2d(x*3,y*3+randomHeight[i]*.7);
				Vec2d D=Vec2d(x+tilt,y+randomHeight[i]);//grass tip
					
					float brushSize=dist(pmouseX,pmouseY,mouseX,mouseY);
					

					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]>.01|| t[i]<-.01){
						t[i]=t[i]*.982;
					}
					
					glColor3f(.2,(randomHeight[i]/30.0),.15);
					
					glBegin(GL_LINE_STRIP);
					for (float p=0;p<=1.0;p=p+.5){
						float b=1.0-p;
						
						Vec2d F=A*b*b*b+B*b*b*p+C*p*p*b+D*p*p*p;
						
						float gradient=p;
						float nTilt=tilt/80;
						glColor4f(.2*gradient-nTilt,(randomHeight[i]/60.0)*gradient-nTilt,.15*gradient-nTilt,.9);
						
						glVertex2f(F.x,F.y);
						
					}
					glEnd();
}