/**
 * Demonstration of doing triangle rasterization with a fragment program.
 * Basic idea:
 *   1. Draw screen-aligned quad / bounding box around the triangle verts.
 *   2. For each pixel in the quad, determine if pixel is inside/outside
 *      the triangle edges.
 *
 * Brian Paul
 * 1 Aug 2007
 */


#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include "shaderutil.h"


static GLint WinWidth = 300, WinHeight = 300;
static char *FragProgFile = NULL;
static char *VertProgFile = NULL;
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
static GLint win = 0;
static GLboolean anim = GL_TRUE;
static GLfloat Zrot = 0.0f;
static GLint uv0, uv1, uv2;


static const GLfloat TriVerts[3][2] = {
   { 50,  50 },
   { 250, 50 },
   { 150, 250 }
};


static void
RotateVerts(GLfloat a,
            GLuint n, const GLfloat vertsIn[][2], GLfloat vertsOut[][2])
{
   GLuint i;
   GLfloat cx = WinWidth / 2, cy = WinHeight / 2;
   for (i = 0; i < n; i++) {
      float x = vertsIn[i][0] - cx;
      float y = vertsIn[i][1] - cy;
      
      vertsOut[i][0] =  x * cos(a) + y * sin(a)  + cx;
      vertsOut[i][1] = -x * sin(a) + y * cos(a)  + cy;
   }
}

static void
ComputeBounds(GLuint n, GLfloat vertsIn[][2],
              GLfloat *xmin, GLfloat *ymin,
              GLfloat *xmax, GLfloat *ymax)
{
   GLuint i;
   *xmin = *xmax = vertsIn[0][0];
   *ymin = *ymax = vertsIn[0][1];
   for (i = 1; i < n; i++) {
      if (vertsIn[i][0] < *xmin)
         *xmin = vertsIn[i][0];
      else if (vertsIn[i][0] > *xmax)
         *xmax = vertsIn[i][0];
      if (vertsIn[i][1] < *ymin)
         *ymin = vertsIn[i][1];
      else if (vertsIn[i][1] > *ymax)
         *ymax = vertsIn[i][1];
   }
}


static void
Redisplay(void)
{
   GLfloat v[3][2], xmin, ymin, xmax, ymax;

   RotateVerts(Zrot, 3, TriVerts, v);
   ComputeBounds(3, v, &xmin, &ymin, &xmax, &ymax);

   glUniform2fv(uv0, 1, v[0]);
   glUniform2fv(uv1, 1, v[1]);
   glUniform2fv(uv2, 1, v[2]);

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glPushMatrix();
   glBegin(GL_POLYGON);
   glVertex2f(xmin, ymin);
   glVertex2f(xmax, ymin);
   glVertex2f(xmax, ymax);
   glVertex2f(xmin, ymax);
   glEnd();
   glPopMatrix();

   glutSwapBuffers();
}


static void
Idle(void)
{
   if (anim) {
      Zrot = glutGet(GLUT_ELAPSED_TIME) * 0.0005;
      glutPostRedisplay();
   }
   else
      abort();
}


static void
Reshape(int width, int height)
{
   glViewport(0, 0, width, height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0, width, 0, height, -1, 1);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}


static void
CleanUp(void)
{
   glDeleteShader(fragShader);
   glDeleteShader(vertShader);
   glDeleteProgram(program);
   glutDestroyWindow(win);
}


static void
Key(unsigned char key, int x, int y)
{
  (void) x;
  (void) y;

   switch(key) {
   case ' ':
   case 'a':
      anim = !anim;
      if (anim)
         glutIdleFunc(Idle);
      else
         glutIdleFunc(NULL);
      break;
   case 'z':
      Zrot = 0;
      break;
   case 's':
      Zrot += 0.05;
      break;
   case 27:
      CleanUp();
      exit(0);
      break;
   }
   glutPostRedisplay();
}


static void
Init(void)
{
   static const char *fragShaderText =
      "uniform vec2 v0, v1, v2; \n"
      "float crs(const vec2 u, const vec2 v) \n"
      "{ \n"
      "   return u.x * v.y - u.y * v.x; \n"
      "} \n"
      "\n"
      "void main() {\n"
      "   vec2 p = gl_FragCoord.xy; \n"
      "   if (crs(v1 - v0, p - v0) >= 0 && \n"
      "       crs(v2 - v1, p - v1) >= 0 && \n"
      "       crs(v0 - v2, p - v2) >= 0) \n"
      "      gl_FragColor = vec4(1.0); \n"
      "   else \n"
      "      gl_FragColor = vec4(0.5); \n"
      "}\n";
   static const char *vertShaderText =
      "void main() {\n"
      "   gl_Position = ftransform(); \n"
      "}\n";

   if (!ShadersSupported())
      exit(1);

   vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
   fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
   program = LinkShaders(vertShader, fragShader);

   glUseProgram(program);

   uv0 = glGetUniformLocation(program, "v0");
   uv1 = glGetUniformLocation(program, "v1");
   uv2 = glGetUniformLocation(program, "v2");
   printf("Uniforms: %d %d %d\n", uv0, uv1, uv2);

   /*assert(glGetError() == 0);*/

   glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
   glEnable(GL_DEPTH_TEST);

   printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));

   assert(glIsProgram(program));
   assert(glIsShader(fragShader));
   assert(glIsShader(vertShader));

   glColor3f(1, 0, 0);
}


static void
ParseOptions(int argc, char *argv[])
{
   int i;
   for (i = 1; i < argc; i++) {
      if (strcmp(argv[i], "-fs") == 0) {
         FragProgFile = argv[i+1];
      }
      else if (strcmp(argv[i], "-vs") == 0) {
         VertProgFile = argv[i+1];
      }
   }
}


int
main(int argc, char *argv[])
{
   glutInit(&argc, argv);
   glutInitWindowSize(WinWidth, WinHeight);
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
   win = glutCreateWindow(argv[0]);
   glewInit();
   glutReshapeFunc(Reshape);
   glutKeyboardFunc(Key);
   glutDisplayFunc(Redisplay);
   if (anim)
      glutIdleFunc(Idle);
   ParseOptions(argc, argv);
   Init();
   glutMainLoop();
   return 0;
}
