//해야할것!
//농구골대 진동


#include <math.h>
#include <stdio.h>
#include <windows.h>
#include "ReadBMP.h" 
#include <gl/glut.h>
typedef float vec3_t[3]; 

#define	checkImageWidth		64
#define	checkImageHeight	64
#define NumberVertices		8
#define NumberFaces			5

typedef float vec3_t[3]; 
typedef float VertexArray[3];
typedef float NormalArray[3];
typedef float TextureCoordsArray[2];
bool	eflag = false;
bool	wflag = false;
bool	qflag = false;
bool	aflag = false;
bool	dflag = false;
bool	sflag = false;
bool	kflag = false;
bool    GolDe = false;
float	size=3.;
float	theta=.0;
float	rtheta=.0;
float	ytheta=.0;
float	thetaDelta=.125;
float	eyeDelta=.125;
float	scale=0.01;
float	scaleDelta=1.125;
double	PI=atan(1.0)*4.0;

int		mouseX = 0;
int		mouseY = 0;
int		mouseState = 0;
int		mouseButton = 0; 
int		projection = 0;
int		depthtest = 1;
int		frontface = 0;
int		compositing = 0;
int		texture = 1;
int		magminfilter = 1;
int		repeating = 1;
int		wireframe = 0;
int		nslice = 5;
int		nside = 5;
int		texturesource = 0;
int		windowWidth;
int		windowHeight;

GLUquadricObj *c;

GLubyte checkImage[checkImageHeight][checkImageWidth][4];
GLint		N=6;
vec3_t rot = {0.,0.,0.};
vec3_t eye = {0.,0.,-5.};
vec3_t center = {0.,0.,0.};
vec3_t color[] = {
	{1.0f, 0.0f, 0.0f},		//red
	{0.0f, 1.0f, 0.0f},		//green
	{0.0f, 0.0f, 1.0f},		//blue
	{1.0f, 1.0f, 0.0f},		//yellow
	{1.0f, 0.0f, 1.0f},		//magenta
	{0.0f, 1.0f, 1.0f},		//cyan
	{1.0f, 1.0f, 1.0f},		//white
	{.25f, .25f, .25f},		//dark gray
	{.60f, .40f, .70f},		//barney purple
	{.98f, .625f, .12f},	//pumpkin orange
	{.98f, .04f, .70f},		//pastel pink
	{.75f, .75f, .75f},		//light gray
	{.60f, .40f, .12f}		//brown
};

MyImageStruct	myImage; 

void makeCheckImage(void)
{
   int i, j, c;
    
   for (i = 0; i < checkImageHeight; i++) {
      for (j = 0; j < checkImageWidth; j++) {
         c = (((i&0x8)==0)^((j&0x8)==0))*255;
         checkImage[i][j][0] = (GLubyte) c;
         checkImage[i][j][1] = (GLubyte) c;
         checkImage[i][j][2] = (GLubyte) c;
         checkImage[i][j][3] = (GLubyte) i*(255/checkImageHeight);
      }
   }
}

void myInit(void)
{    
	glClearColor(0.0, 0.0, 0.0, 0.0);
	
	ReadBMP("pan.bmp", &myImage); 
	glBindTexture(GL_TEXTURE_2D, 1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, myImage.Width, myImage.Height, 
		0, GL_RGB, GL_UNSIGNED_BYTE, myImage.Pixels);

	ReadBMP("bask.bmp", &myImage); 
	glBindTexture(GL_TEXTURE_2D, 2);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, myImage.Width, myImage.Height, 
		0, GL_RGB, GL_UNSIGNED_BYTE, myImage.Pixels);

	ReadBMP("Cou.bmp", &myImage); 
	glBindTexture(GL_TEXTURE_2D, 3);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, myImage.Width, myImage.Height, 
		0, GL_RGB, GL_UNSIGNED_BYTE, myImage.Pixels);

	ReadBMP("Bar.bmp", &myImage); 
	glBindTexture(GL_TEXTURE_2D, 4);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, myImage.Width, myImage.Height, 
		0, GL_RGB, GL_UNSIGNED_BYTE, myImage.Pixels);


	glEnable(GL_TEXTURE_2D);
	glEnable(GL_DEPTH_TEST);
	glPolygonMode(GL_BACK, GL_LINE);
	glPolygonMode(GL_FRONT, GL_FILL);
}
void myAxis(void)
{
	int	i;
	glColor3f(.98, .04, .70); 
	glBegin(GL_LINES);
	for(i=0; i<=N; i++) {
		glVertex2f(-size+2.0*i*size/N, -size);
		glVertex2f(-size+2.0*i*size/N, size);
		glVertex2f(-size, -size+2.0*i*size/N);
		glVertex2f(size, -size+2.0*i*size/N);
	}
	glEnd();
	glColor3f(.25, .25, .25); 
	glBegin(GL_LINES);
		glVertex2f(0, -size);
		glVertex2f(0, size);
		glVertex2f(-size, 0);
		glVertex2f(size, 0);
	glEnd();
}
void DrawTexturedMesh(VertexArray *vertices, NormalArray *normalVectors, 
	GLint *faces, GLint nFaces, GLint verticesPerFace,
	TextureCoordsArray *textureCoords, GLint *textureIndexes) { 
	int  j, k, n=0, f; 
	if(wireframe) f = GL_LINE_LOOP;
	else f = GL_POLYGON;
	for (j=0; j<nFaces; j++) { 
		glBegin(f); 
		glNormal3fv(normalVectors[j]); 
		for (k=0; k<verticesPerFace; k++) { 
			glTexCoord2fv(textureCoords[textureIndexes[n]]); 
			glVertex3fv(vertices[faces[n++]]); 
		} 
		glEnd(); 
	} 
}
void DrawSphere(float radius, int numberSlices, int numberSides)
{
	GLint                numberVertices;
	GLint                numberFaces;
	VertexArray         *vertices;
	NormalArray         *normals;
	GLint               *faces; 
	TextureCoordsArray  *textureCoordinates; 
	GLint               *textureIndexes;
	int                  j, k, n, m;
	float                x, y, z;
	float                u, v;
	float                uInc, vInc;

	// allocate the needed memory for the data
	numberVertices = (numberSides+1) * (numberSlices+1);
	numberFaces = (numberSides) * (numberSlices);
	vertices = (VertexArray *) malloc( sizeof(VertexArray) * numberVertices);
	normals = (NormalArray *) malloc( sizeof(NormalArray) * numberFaces);
	faces = (GLint *) malloc( sizeof(GLint) * numberFaces * 4);
	textureCoordinates = (TextureCoordsArray *)
	malloc( sizeof(TextureCoordsArray) * numberVertices);
	textureIndexes = (GLint *) malloc( sizeof(GLint) * numberFaces * 4);

	if (vertices != 0 && normals != 0 && faces != 0 && 
		textureCoordinates != 0 && textureIndexes != 0) {
		vInc = 2.*PI/numberSides;
		uInc = PI/numberSlices;
		n = 0;
		for (k=0, u = -0.5*PI; k<=numberSlices; k++, u += uInc) {
			for (j=0, v = 0.0; j<=numberSides; j++, v += vInc) {
				// Generate the vertices and texture coordinates around this slice
				vertices[n][0] = radius*cos(u)*cos(v);
				vertices[n][1] = radius*cos(u)*sin(v);
				vertices[n][2] = radius*sin(u);

				textureCoordinates[n][0] = (float) j / (float) numberSides;
				textureCoordinates[n][1] = (float) k / (float) numberSlices;

				if (n < numberFaces) {
					// Calculate the normal vector for the face using the middle
					//   point on the face
					x = radius*cos(u+uInc*0.5)*cos(v+0.5*vInc);
					y = radius*cos(u+uInc*0.5)*sin(v+0.5*vInc);
					z = radius*sin(u+uInc*0.5);
					normals[n][0] = x / radius;
					normals[n][1] = y / radius;
					normals[n][2] = z / radius;
				}
				n++;
			}
		}

		// Create the faces
		n = 0;
		m = 0;
		for (k=0; k<numberSlices; k++) {
			for (j=0; j<numberSides; j++) {
				// Generate the face and texture indexes for this face
				faces[n] = textureIndexes[n] = m;                n++;
				faces[n] = textureIndexes[n] = m+1;              n++;
				faces[n] = textureIndexes[n] = m+1+numberSides+1;  n++;
				faces[n] = textureIndexes[n] = m+numberSides+1;  n++;
				m++;
			}
			m++;
		}
		DrawTexturedMesh(vertices, normals, faces, numberFaces, 4,
			textureCoordinates, textureIndexes); 
	}

	// Reclaim the allocated memory
	if (vertices != NULL)           free( vertices );
	if (normals != NULL)            free( normals  );
	if (faces != NULL)              free( faces    );
	if (textureCoordinates != NULL) free( textureCoordinates );
	if (textureIndexes != NULL)     free( textureIndexes );
}

void SEv(int jump) // shotevent 점프 - 뛰는 값 수비수 뛰기결정
{
	if(kflag)
	{
		if(theta>3)
		{
			kflag=false;
			theta=0;
		}
		glTranslatef(0,jump*sin(theta),0);
	}
}

void SEv2() // shotevent  공격수 뛰기 결정
{
	if(kflag)
	{
		if(theta>10)
		{
			kflag=false;
			theta=0;
		}
		glTranslatef(0,50*sin(theta),0);
	}
}

void shake() // shake  흔들기.
{
	if(kflag)
	{
		if(rtheta>10000)//끝나는 속도 조절
		{
			kflag=false;
			theta=0;
		}

		if(4*rtheta>500)//시작속도 조절 
			glTranslatef(sin(theta*10),0,0);//여기서 theta값을 늘리면 쉐이크 강도 증가
	}
}

void Defender(int x, int z, int lo, int jump) //디펜더들 x : x좌표, z : z 좌표, lo : 디펜더 포지션 각도, jump : SEv에 점프를 다시 입력
{

	glTranslatef(0+x,0,0+z);
	glRotatef(lo,0,1,0);
	
	glPushMatrix();

		SEv(jump);

		glPushMatrix();		
			glTranslatef(0,9,0);
			glutWireCube(3.0);
			glTranslatef(0,4,0);
			glutWireSphere(4,10,10);

			glPushMatrix(); //all

				glPushMatrix(); //body
					glTranslatef(0,-13,0);
					glColor3f(1,1,.6);
					glScalef(1,1.5,0.5);
					glutWireCube(10.0);
				glPopMatrix();
			////////////////////// arm
				glPushMatrix(); //left sho

					glRotatef(theta,0,0,1);
					glTranslatef(6,-7,0);
					glutWireSphere(2,10,10);

					glPushMatrix();
						glTranslatef(0,6,0);
						glScalef(0.5,2,0.5);
						glutWireCube(5.0);

						glPushMatrix();

							glTranslatef(0,3,0);
							glScalef(2,0.5,2);
							//glRotatef(30,0,0,1);
							glutWireSphere(2,10,10);

							glPushMatrix();
								glTranslatef(0,4,0);
								glScalef(0.5,2,0.5);
								glutWireCube(5.0);
							glPopMatrix();


						glPopMatrix();

					glPopMatrix();

				glPopMatrix();

				glPushMatrix();//right sho
					glTranslatef(-6,-7,0);
					glutWireSphere(2,10,10);

					glPushMatrix();
						glTranslatef(0,6,0);
						glScalef(0.5,2,0.5);
						glutWireCube(5.0);

						glPushMatrix();

							glTranslatef(0,3,0);
							glScalef(2,0.5,2);
							glutWireSphere(2,10,10);

							glPushMatrix();
								glTranslatef(0,4,0);
								glScalef(0.5,2,0.5);
								glutWireCube(5.0);
							glPopMatrix();


						glPopMatrix();

					glPopMatrix();

				glPopMatrix();

			////////////////////////////////// arm end


				glPushMatrix(); //ass
						glTranslatef(0,-22,0);
						glScalef(2,1,0.5);
						glutWireCube(5.0);
				glPopMatrix();


				///////////leg

				glPushMatrix(); //right
						glTranslatef(3.5,-33,0);
						glScalef(0.7,4,0.5);
						glutWireCube(5.0);
				glPopMatrix();

				glPushMatrix(); //left
						glTranslatef(-3.5,-33,0);
						glScalef(0.7,4,0.5);
						glutWireCube(5.0);
				glPopMatrix();

				//leg end


			glPopMatrix();

		glPopMatrix();

	glPopMatrix();


}
void shotEvent(int r)
{
	if(kflag)
	{
		if(theta>3)
		{
			kflag=false;
			theta=0;
		}
		glRotatef(-r*sin(theta),1,0,0);
	}
}



void shooter(int jump)
{
	glPushMatrix();
	 
		SEv(jump); //슈터의 점프 높이

		glPushMatrix();		
				glTranslatef(0,9,0);
				glutWireCube(3.0);
				glTranslatef(0,4,0);
				glutWireSphere(4,10,10);

				glPushMatrix(); //all

					glPushMatrix(); //body
						glTranslatef(0,-13,0);
						glColor3f(1,1,.6);
						glScalef(1,1.5,0.5);
						glutWireCube(10.0);
					glPopMatrix();
				////////////////////// arm
					glPushMatrix(); //오른쪽 어깨

					glRotatef(theta,0,0,1);
					glTranslatef(6,-7,0);
					shotEvent(-5);
					glRotatef(-30,1,0,0);
					glutWireSphere(2,10,10);

					glPushMatrix();

						glTranslatef(0,6,0);
						glScalef(0.5,2,0.5);
						glutWireCube(5.0);
						
						glPushMatrix();

							glTranslatef(0,3,0);
							glScalef(2,0.5,2);
							glRotatef(80,1,0,0);
							shotEvent(100); //손 꺾이는 각도
							glutWireSphere(2,10,10);

							glPushMatrix();
								glTranslatef(0,4,0);
								glScalef(0.5,2,0.5);
								glutWireCube(5.0);
							glPopMatrix();


						glPopMatrix();

					glPopMatrix();

				glPopMatrix();
				
				glPushMatrix(); //왼쪽 어깨

					glTranslatef(-6,-7,0);
					shotEvent(20); //꺾이는 각도
					glutWireSphere(2,10,10);

					glPushMatrix();

						glTranslatef(0,6,0);
						glScalef(0.5,2,0.5);
						glutWireCube(5.0);

						glPushMatrix();

							glTranslatef(0,3,0);
							glScalef(2,0.5,2);
							glRotatef(-30,0,0,1);
							//shotEvent(-15);
							glutWireSphere(2,10,10);

							glPushMatrix();
								glTranslatef(0,4,0);
								glScalef(0.5,2,0.5);
								glutWireCube(5.0);
							glPopMatrix();


						glPopMatrix();

					glPopMatrix();

				glPopMatrix();

				////////////////////////////////// arm end


					glPushMatrix(); //ass
							glTranslatef(0,-22,0);
							glScalef(2,1,0.5);
							glutWireCube(5.0);
					glPopMatrix();


					///////////leg

					glPushMatrix(); //right
							glTranslatef(3.5,-33,0);
							glScalef(0.7,4,0.5);
							glutWireCube(5.0);
					glPopMatrix();

					glPushMatrix(); //left
							glTranslatef(-3.5,-33,0);
							glScalef(0.7,4,0.5);
							glutWireCube(5.0);
					glPopMatrix();

					//leg end


				glPopMatrix();

			glPopMatrix();

		glPopMatrix();

}
void myIdle(void)
{	
	if(eflag)
	{
		rtheta+=0.1;		
	}
	if(qflag)
	{
		rtheta+=0.1;		
	}
	if(wflag)// 공속도조절
	{
		rtheta+=.6;		
	}
	if(aflag)
	{
		rtheta+=.01;		
	}
	if(dflag)
	{
		rtheta+=.01;		
	}
	if(sflag)
	{
		if(ytheta<135)
			rtheta+=.01;
		else
			rtheta-=.01;
		ytheta+=.01;
		
	}
	if(kflag)//수비수 점프력
	{
		theta+=0.01;
	}

	glutPostRedisplay();
}

//슛 이벤트 로테이션 값 조정
void shotevent()
{
	if(eflag)
	{
		if(rtheta>190)
		{
			eflag=false;
			rtheta=0;			
		}
		glRotatef(rtheta,-1,1,0);
		
	}
	if(qflag)
	{
		if(rtheta>190)
		{
			qflag=false;
			rtheta=0;			
		}
		glRotatef(-rtheta,1,1,0);
		
	}
	if(wflag)
	{
		if(rtheta>190)
		{
			wflag=false;
			rtheta=0;			
		}
		glRotatef(-rtheta,1,0,0);
		
	}
	if(aflag)
	{
		if(rtheta>210)
		{
			aflag=false;
			rtheta=0;			
		}
		glTranslatef(-rtheta/25,rtheta/25,2*-rtheta);		
	}
	if(dflag)
	{
		if(rtheta>210)
		{
			dflag=false;
			rtheta=0;
		}
		glRotatef(-rtheta,0.2,0,1);
	}
	if(sflag)
	{
		if(ytheta>210)
		{
			sflag=false;
			rtheta=0;
			ytheta=0; 
		}			
		glTranslatef(0,rtheta/25,2*-ytheta);	
	}
}
void myDisplay (void)
{
	 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	if(!projection)
		gluLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], 0, 1, 0);
	glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
	glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
	glRotatef(rot[2], 0.0f, 0.0f, 1.0f);
	glScalef(scale, scale, scale);
	
	

		
	glPushMatrix();
		glColor3fv(color[2]);
		glBindTexture(GL_TEXTURE_2D, 3);//바닥
		glBegin(GL_QUADS);
		glTexCoord2f(0.0, 0.0); glVertex3f(200,-30,150);
		glTexCoord2f(1.0, 0.0); glVertex3f(200,-30,-150);
		glTexCoord2f(1.0, 1.0); glVertex3f(-200,-30,-150);
		glTexCoord2f(0.0, 1.0); glVertex3f(-200,-30,150);
		glEnd();
	glPopMatrix();

	glPushMatrix();
		
		
		////////////Defender  //디펜더들 x : x좌표, z : z 좌표, lo : 디펜더 포지션 각도, jump : SEv에 점프를 다시 입력
		glPushMatrix();
			Defender(0,60,0,60);			//가운데 사람
		glPopMatrix();

		glPushMatrix();
			Defender(35,75,-75,20);
		glPopMatrix();
		glPushMatrix();
			Defender(-45,80,40,40);
		glPopMatrix();

		//////////////////////////
		glPushMatrix();
			glTranslatef(0,0,100);
			shooter(30); // 30 -> 점프 높이
		glPopMatrix();

		//////////////////////////////////////////
	glPopMatrix();
	

	//공
	glPushMatrix();

		//SEv2();
		
		shotevent();
		glTranslatef(0,0,100);
		glTranslatef(3,25,-5);
		int aaa =4*rtheta;
		glRotatef(aaa,1,1,1);
		
		glBindTexture(GL_TEXTURE_2D, 2);
		DrawSphere(4., 10, 10);
	glPopMatrix();

	
	shake();
	///////////골대
	glPushMatrix();
		glTranslatef(0,0,-100);
		glPushMatrix();
		glBindTexture(GL_TEXTURE_2D, 4);
	
			glPushMatrix();
				glTranslatef(0,10,0);
				glColor3f(1,1,.6);
				glScalef(0.5,10,0.5);
				glutSolidCube(10.0);
				glPopMatrix();
			glPopMatrix();

		glPushMatrix();
			glBindTexture(GL_TEXTURE_2D, 1);//바닥
			glTranslatef(0,50,35);
			glRotatef(-90,0,0,1);
			glRotatef(90,1,0,0);
			glColor3fv(color[1]);
			glBegin(GL_QUADS);
			glTexCoord2f(0.0, 0.0); glVertex3f(20,-30,30);
			glTexCoord2f(1.0, 0.0); glVertex3f(20,-30,-30);
			glTexCoord2f(1.0, 1.0); glVertex3f(-20,-30,-30);
			glTexCoord2f(0.0, 1.0); glVertex3f(-20,-30,30);
			glEnd();
		glPopMatrix();
	
	glPopMatrix();

	glFlush();
	glutSwapBuffers();
}

void myLookAt(int key)
{
	if(key == GLUT_KEY_UP) {
		eye[2] = eye[2]-cos(theta)*eyeDelta;
		eye[0] = eye[0]+sin(theta)*eyeDelta;
	}
	else if(key == GLUT_KEY_DOWN) {
		eye[2] = eye[2]+cos(theta)*eyeDelta;
		eye[0] = eye[0]-sin(theta)*eyeDelta;
	}
	center[2] = eye[2]-cos(theta);
	center[0] = eye[0]+sin(theta);
}

void myResize (int width, int height)
{
	glClearColor(.75, .75, .75, 0.0);
    if (!height) return;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	if(projection) {
		glOrtho(-size, size, -size, size, -size, size); 
		eye[2] = 0.;
	}
    else {
		gluPerspective(60., (float)width/height, .1, 10.);
		eye[2] = 5.;
		myLookAt(0);
	}
	glMatrixMode(GL_MODELVIEW);
	windowWidth=width;
	windowHeight=height;
}

void mySKeyboard (int key, int x, int y)
{
    switch (key) {
		case GLUT_KEY_UP : break;
		case GLUT_KEY_DOWN : break;
		case GLUT_KEY_LEFT : theta-=thetaDelta; break;
		case GLUT_KEY_RIGHT : theta+=thetaDelta; break;
		default : return;
    }
	myLookAt(key);
	glutPostRedisplay();
}

void myKeyboard (unsigned char key, int x, int y)
{
	switch (key)
	{
	case '1':wflag=true;
		kflag=true;
		break;
	case '2':qflag=true;
		kflag=true;
		break;
	case '3':eflag=true;
		kflag=true;
		break;
	case '4':dflag=true;
		kflag=true;
		break;
	case '5':sflag=true;
		kflag=true;
		break;
	case 'p':
		projection = !projection;
		myResize(windowWidth, windowHeight);
	break;
	case 'd':
		depthtest = !depthtest;
		if(depthtest) glEnable(GL_DEPTH_TEST);
		else glDisable(GL_DEPTH_TEST);
	break;
	case 'f':
		frontface = !frontface;
		if(frontface) glFrontFace(GL_CW);
		else glFrontFace(GL_CCW);
	break;
	case 'r':
		repeating = !repeating;
		if(repeating) {
			glBindTexture(GL_TEXTURE_2D, 1);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
			glBindTexture(GL_TEXTURE_2D, 2);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
			glBindTexture(GL_TEXTURE_2D, 3);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		}
		else {
			glBindTexture(GL_TEXTURE_2D, 1);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
			glBindTexture(GL_TEXTURE_2D, 2);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
			glBindTexture(GL_TEXTURE_2D, 3);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		}
	break;
	case 'c':
		compositing = !compositing;
		if(compositing) {
			glBindTexture(GL_TEXTURE_2D, 1);
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
			glBindTexture(GL_TEXTURE_2D, 2);
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
			glBindTexture(GL_TEXTURE_2D, 3);
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
		}
		else {
			glBindTexture(GL_TEXTURE_2D, 1);
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
			glBindTexture(GL_TEXTURE_2D, 2);
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
			glBindTexture(GL_TEXTURE_2D, 3);
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
		}
	break;
	case 'm':
		magminfilter = !magminfilter;
		if(magminfilter) {
			glBindTexture(GL_TEXTURE_2D, 1);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
			glBindTexture(GL_TEXTURE_2D, 2);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
			glBindTexture(GL_TEXTURE_2D, 3);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
		}
		else {
			glBindTexture(GL_TEXTURE_2D, 1);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
			glBindTexture(GL_TEXTURE_2D, 2);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
			glBindTexture(GL_TEXTURE_2D, 3);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
		}
	break;
	case 't':
		texture = !texture;
		if(texture) glEnable(GL_TEXTURE_2D);
		else glDisable(GL_TEXTURE_2D);
	break;
	case 'z':
		scale*=scaleDelta;
	break;
	case 'x':
		scale/=scaleDelta;
	break;
	}
	glutPostRedisplay();
}

void myMouse(int btn, int state, int x, int y)
{
	if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
		
		mouseState=state;
		mouseButton=btn;
		mouseX=x;
		mouseY=y;
	}
	else if(btn==GLUT_LEFT_BUTTON && state == GLUT_UP)
		mouseState=-1;
	else return;
	glutPostRedisplay();
}

void myMotion(int x, int y)
{
	if(mouseButton == GLUT_LEFT_BUTTON && mouseState == GLUT_DOWN) {
		rot[1] -= (mouseX - x)/5.;
		rot[0] -= (mouseY - y)/5.;
		glutPostRedisplay();
		mouseX=x;
		mouseY=y;
	}
	
	
}

void main (void)
{
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(500,500);
	glutCreateWindow("MTWTFFF");
	glutDisplayFunc(myDisplay);
	glutReshapeFunc(myResize);
	glutKeyboardFunc(myKeyboard);
    glutSpecialFunc(mySKeyboard);
	glutIdleFunc(myIdle);
	glutMouseFunc(myMouse);
	glutMotionFunc(myMotion);
	myInit();
	glutMainLoop();
}
