// Simple Demo for GLSL by Ingemar Ragnemalm,
// originally based on code from www.lighthouse3d.com.
// May require GLEW to compile on some systems.
// 090209: Slightly more trimmed down. Portable #include.

#ifdef __APPLE__
	#include <GLUT/glut.h>
#else
	#include <GL/glut.h>
#endif
#include <stdio.h>

void changeSize(int w, int h)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0, 0, w, h);
	gluPerspective(45,1.0* w / h,1,1000);
	glMatrixMode(GL_MODELVIEW);
}

void renderScene(void)
{
	static float a = 0;
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glLoadIdentity();
	gluLookAt(0.0,0.0,5.0, 
		      0.0,0.0,-1.0,
			  0.0f,1.0f,0.0f);

	glRotatef(a,0,1,1);
	glutSolidTeapot(1);
	a+=0.1;
	glutSwapBuffers();
}

// Hard-coded shaders; you should read them from files
char *vs = "void main() {gl_Position = ftransform();}";
char *fs = "void main() {gl_FragColor = vec4(0.2,0.5,0.8,1.0);}";

void setShaders()
{
	GLuint v,f,p;

	v = glCreateShader(GL_VERTEX_SHADER);
	f = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(v, 1, &vs, NULL);
	glShaderSource(f, 1, &fs, NULL);
	glCompileShader(v);
	glCompileShader(f);
	p = glCreateProgram();
	glAttachShader(p,v);
	glAttachShader(p,f);
	glLinkProgram(p);
	glUseProgram(p);
}

int main(int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutCreateWindow("Microshader example");

	glutDisplayFunc(renderScene);
	glutIdleFunc(renderScene);
	glutReshapeFunc(changeSize);

	glEnable(GL_DEPTH_TEST);
	glClearColor(1.0,1.0,1.0,1.0);
	glEnable(GL_CULL_FACE);

	setShaders();
	glutMainLoop();
	return 0;
}

