//
// shader.cc for graviball in /u/a2/yousfi_r/projets/graviball
//
// Made by razik yousfi
// Login   <yousfi_r@epita.fr>
//
// Started on  Sat Nov 18 19:37:42 2006 razik yousfi
// Last update Mon Nov 20 22:17:53 2006 
//

#include <math.h>
#include "shader.hh"
#include "../factory/vertex.h"

void	shader_dummy (struct s_face&, struct s_shader&)
{
}

void	shader_rotate (struct s_face& face, struct s_shader& shader)
{
  float	angle = 0;
  float	cosa;
  float	sina;
  float	dx;
  float	dy;

  angle = shader.args[0] * gl_vertex.time * 3.14159f / 180;
  cosa = cos (angle);
  sina = sin (angle);
  for (int i = 0; i < (int)face.texcoords.size (); ++i)
  {
    dx = face.texcoords[i].u - 0.5f;
    dy = face.texcoords[i].v - 0.5f;
    face.curTexcoords[i].u = dx * cosa - dy * sina + 0.5f;
    face.curTexcoords[i].v = dx * sina + dy * cosa + 0.5f;
  }
}

void	shader_scroll (struct s_face& face, struct s_shader& shader)
{
  float	time = (float)gl_vertex.time / 1000.f;
  float	dx = shader.args[0] * time - floor (shader.args[0] * time);
  float	dy = shader.args[1] * time - floor (shader.args[1] * time);

  for (int i = 0; i < (int)face.texcoords.size (); ++i)
  {
    face.curTexcoords[i].u = face.texcoords[i].u + dx;
    face.curTexcoords[i].v = face.texcoords[i].v + dy;
  }
}

void	shader_turb (struct s_face& face, struct s_shader& shader)
{
  float	dx;
  float	dy;

  dx = shader.args[1] * gl_vertex.time + shader.args[2];
  dy = shader.args[0];

  for (int i = 0; i < (int)face.texcoords.size (); ++i)
  {
    face.curTexcoords[i].u = face.texcoords[i].u +
      sin (face.texcoords[i].u * dy + dx) * dy;
    face.curTexcoords[i].v = face.texcoords[i].v +
      sin (face.texcoords[i].v * dy + dx) * dy;
  }
}

void	shader_wave (struct s_face& face, struct s_shader& shader)
{
  int		idx = (int)shader.args[0];

  for (int i = 0; i < (int)face.vertices.size (); ++i)
  {
    if (idx == 0)
      face.curVertices[i].x = face.vertices[i].x + shader.args[1] *
	sin (gl_vertex.time * shader.args[2] + shader.args[3] * i);
    else if (idx == 1)
      face.curVertices[i].y = face.vertices[i].y + shader.args[1] *
	sin (gl_vertex.time * shader.args[2] + shader.args[3] * i);
    else if (idx == 2)
      face.curVertices[i].z = face.vertices[i].z + shader.args[1] *
	sin (gl_vertex.time * shader.args[2] + shader.args[3] * i);
  }
}

void	shader_rotzoom (struct s_face& face, struct s_shader& shader)
{
  float	angle = 0;
  float	cosa;
  float	sina;
  float	dx;
  float	dy;

  angle = shader.args[0] * gl_vertex.time * 3.14159f / 180;
  cosa = cos (angle);
  sina = sin (angle);
  for (int i = 0; i < (int)face.texcoords.size (); ++i)
  {
    dx = face.texcoords[i].u - 0.5f;
    dy = face.texcoords[i].v - 0.5f;
    face.curTexcoords[i].u = dx * cosa - dy * sina + 0.5f;
    face.curTexcoords[i].v = dx * sina + dy * cosa + 0.5f;
    if (face.curTexcoords[i].u < 0)
      face.curTexcoords[i].u = 0;
    else if (face.curTexcoords[i].u > 1)
      face.curTexcoords[i].u = 1;
    else if (face.curTexcoords[i].v < 0)
      face.curTexcoords[i].v = 0;
    else if (face.curTexcoords[i].v > 1)
      face.curTexcoords[i].v = 1;
  }
}

void	shader_color (struct s_face& face, struct s_shader& shader)
{
  float		max = shader.args[2];
  float		min = shader.args[1];

  face.color[(unsigned int)shader.args[0] % 4] = min + (max - min) * sin (shader.args[3] * gl_vertex.time);
}
