#include <math.h>
#include <GL/glut.h>

void modulator(GLfloat *ctpnts, GLint arrsize, GLdouble ampl);

void display(void)
{
#define NUMKNOTS 8
	static GLfloat ctpnts[8][8][3];
	static GLfloat knots[NUMKNOTS];
	GLint i, j;
	GLUnurbs *nobj;
	GLint initialized = 0;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glEnable(GL_SMOOTH);
	glClearColor(1, 1, 1, 1);
	glColor3f(0, 0, 1);
	gluLookAt(0, 1, 3.5, 0, 0, 0, 0, 1, 0);

	glTranslatef(-1.5, 0, 0);

	if(!initialized) {
		for(i=0; i < 8; i++) {
			for(j=0; j < 8; j++) {
				ctpnts[i][j][0] = j;
				ctpnts[i][j][1] = 0;
				ctpnts[i][j][2]  = i;
			}
			knots[i] = i;
		}
		initialized = !initialized;
	}

	modulator((GLfloat *)ctpnts, 8, 0.6);

	nobj = gluNewNurbsRenderer();
	gluNurbsProperty(nobj, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);

	gluBeginSurface(nobj);
	gluNurbsSurface(nobj, NUMKNOTS, knots, NUMKNOTS, knots, 8*3, 3, &ctpnts[0][0][0], 4, 4, GL_MAP2_VERTEX_3);
	gluEndSurface(nobj);

	gluDeleteNurbsRenderer(nobj);

	glutSwapBuffers();
}

void modulator(GLfloat *ctpnts, GLint arrsize, GLdouble ampl)
{
	GLint i, j;
	static GLdouble incr = 0;

	for(i=0; i < arrsize; i++) {
		for(j=0; j < arrsize; j++) {
			incr += 0.0001;
			ctpnts[(i*arrsize*3) + (j*3) + 1] = ampl*sin(i+j+incr);
		}
	}
}


void idle(void)
{
	//usleep(100000);
	glutPostRedisplay();
}

void reshape(int w, int h)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0f, (GLdouble)w/h, 0.1, 300.0);
	glMatrixMode(GL_MODELVIEW);
	glViewport(0, 0, w, h);
}


int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE | GLUT_STENCIL);
	glutInitWindowPosition(20, 20);
	glutInitWindowSize(400, 300);
	glutCreateWindow("ex_1");

	glutReshapeFunc(reshape); 
	glutDisplayFunc(display);
	glutIdleFunc(idle);

	glutMainLoop();

	return(0);

}

