/**
 * 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/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include "extfuncs.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_func(uv0, 1, v[0]);
   glUniform2fv_func(uv1, 1, v[1]);
   glUniform2fv_func(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_func(fragShader);
   glDeleteShader_func(vertShader);
   glDeleteProgram_func(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);

   GetExtensionFuncs();

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

   glUseProgram_func(program);

   uv0 = glGetUniformLocation_func(program, "v0");
   uv1 = glGetUniformLocation_func(program, "v1");
   uv2 = glGetUniformLocation_func(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_func(program));
   assert(glIsShader_func(fragShader));
   assert(glIsShader_func(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);
   glutInitWindowPosition( 0, 0);
   glutInitWindowSize(WinWidth, WinHeight);
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
   win = glutCreateWindow(argv[0]);
   glutReshapeFunc(Reshape);
   glutKeyboardFunc(Key);
   glutDisplayFunc(Redisplay);
   if (anim)
      glutIdleFunc(Idle);
   ParseOptions(argc, argv);
   Init();
   glutMainLoop();
   return 0;
}
