#include<windows.h>
#include"gl/freeglut.h"
#include <math.h>

#define N 20
#define PI 3.14159265358979323846
//a^2>b^2 - пузатий
//a^2<b^2 - худий
const double a1 = 0.3;
const double b1 = 0.6;
const double c1 = 0.9;
double u;//[-pi/2,pi/2]
double v;//[0,2pi]



double f(double x, double y)
{
	if ((x != 0) || (y != 0))return 5.0 * sin((x * x + y * y)) / (x * x + y * y); else return 5.0;
}



void resize(int width, int height)
{
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-5, 5, -5, 5, 2, 12);
	gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
	glMatrixMode(GL_MODELVIEW);
}
void trinormal(GLfloat* a, GLfloat* b, GLfloat* c, GLfloat* n)
{
	//n = b-a x c-b
	GLfloat v[3] = { b[0] - a[0],b[1] - a[1],b[2] - a[2] };
	GLfloat w[3] = { c[0] - b[0],c[1] - b[1],c[2] - b[2] };
	n[0] = a[1] * b[2] - a[2] * b[1];
	n[1] = -(a[0] * b[2] - a[2] * b[0]);
	n[2] = a[0] * b[1] - a[1] * b[0];
}


void display(void)
{
	double h1 = PI / N;
	double h2 = PI / N * 2.0;
	GLUquadricObj* quadObj;
	GLfloat front_color[] = { 0,1,0,1 };
	GLfloat back_color[] = { 0,0,1,1 };
	GLfloat front_emission[] = { 1,1,0,1 };
	GLfloat back_emission[] = { 0,0,1,1 };
	quadObj = gluNewQuadric();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, front_color);
	glMaterialfv(GL_BACK, GL_DIFFUSE, back_color);
	//glMaterialfv(GL_FRONT, GL_EMISSION, front_emission);
	//glMaterialfv(GL_BACK, GL_EMISSION, back_emission);

	//glPushMatrix();
	//glRotated(110, -1,1,0);

	glRotated(0.1, -1, 1, 0);
	//gluCylinder(quadObj, 1, 0.5, 2, 10, 10);
	gluSphere(quadObj, 3, 6, 5);

	GLfloat n[3];

	GLfloat a[3], b[3], c[3], d[3];
	glEnable(GL_NORMALIZE);
	for (int i = 0; i <= N; i++)
	{
		for (int j = 0; j <= N; j++)
		{
			a[0] = a1 * cos((i - N / 2) * h1) * cos(PI + (j - N / 2) * h2) + b1 * sin((i - N / 2) * h1) * sin(PI + (j - N / 2) * h2);
			a[1] = a1 * cos((i - N / 2) * h1) * sin(PI + (j - N / 2) * h2) - b1 * sin((i - N / 2) * h1) * cos(PI + (j - N / 2) * h2);
			a[2] = c1 * sin((i - N / 2) * h1);
			b[0] = a1 * cos((i - N / 2) * h1) * cos(PI + (j + 1 - N / 2) * h2) + b1 * sin((i - N / 2) * h1) * sin(PI + (j + 1 - N / 2) * h2);
			b[1] = a1 * cos((i - N / 2) * h1) * sin(PI + (j + 1 - N / 2) * h2) - b1 * sin((i - N / 2) * h1) * cos(PI + (j + 1 - N / 2) * h2);
			b[2] = c1 * sin((i - N / 2) * h1);
			c[0] = a1 * cos((i + 1 - N / 2) * h1) * cos(PI + (j - N / 2) * h2) + b1 * sin((i + 1 - N / 2) * h1) * sin(PI + (j - N / 2) * h2);
			c[1] = a1 * cos((i + 1 - N / 2) * h1) * sin(PI + (j - N / 2) * h2) - b1 * sin((i + 1 - N / 2) * h1) * cos(PI + (j - N / 2) * h2);
			c[2] = c1 * sin((i + 1 - N / 2) * h1);
			d[0] = a1 * cos((i + 1 - N / 2) * h1) * cos(PI + (j + 1 - N / 2) * h2) + b1 * sin((i + 1 - N / 2) * h1) * sin(PI + (j + 1 - N / 2) * h2);
			d[1] = a1 * cos((i + 1 - N / 2) * h1) * sin(PI + (j + 1 - N / 2) * h2) - b1 * sin((i + 1 - N / 2) * h1) * cos(PI + (j + 1 - N / 2) * h2);
			d[2] = c1 * sin((i + 1 - N / 2) * h1);

			//trinormal(a,b,c,n);
			//glNormal3f(n[0],n[1],n[2]);
			/*glBegin(GL_TRIANGLE_STRIP);
			glVertex3f(a[0],a[1],a[2]);
			glVertex3f(b[0],b[1],b[2]);
			glVertex3f(c[0],c[1],c[2]);
			glVertex3f(d[0],d[1],d[2]);
			glEnd();*/
		}
	}



	//glPopMatrix();
	gluDeleteQuadric(quadObj);
	glutSwapBuffers();
}



void main(int argc, char* argv[])
{
	float pos[4] = { 3,3,3,1 }; float pos1[4] = { -3,-3,3,1 };
	float dir[3] = { -1,-1,1 }; float dir1[3] = { 1,1,1 };

	GLfloat mat_specular[] = { 1,1,1,1 };
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
	glutInitWindowSize(400, 400);
	glutInitWindowPosition(50, 10);

	glutCreateWindow("Glaux Template");
	glutIdleFunc(display);
	glutReshapeFunc(resize);


	glEnable(GL_DEPTH_TEST);

	//glEnable(GL_COLOR_MATERIAL);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glLightfv(GL_LIGHT0, GL_POSITION, pos);
	glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);

	//glEnable(GL_LIGHT1);
	//glLightfv(GL_LIGHT1, GL_POSITION, pos1);
	//glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, dir1);


	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialf(GL_FRONT, GL_SHININESS, 128.0);


	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

	glutDisplayFunc(display);
	glutMainLoop();
}