/* COMPATIBILITY 
	- HLSL compilers
	- Cg	compilers
	- FX11 compilers
*/

/*

	Copyright (C) 2007 guest(r) - guest.r@gmail.com

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include "../../compat_includes.inc"
uniform COMPAT_Texture2D(decal) : TEXUNIT0;
uniform float4x4 modelViewProj;

struct out_vertex
{
	float4 position : COMPAT_POS;
	float2 texCoord : TEXCOORD0;
#ifndef HLSL_4
	float4 Color    : COLOR;
#endif
};

out_vertex main_vertex(COMPAT_IN_VERTEX)
{
	out_vertex OUT;
#ifdef HLSL_4
	float4 position = VIN.position;
	float2 texCoord = VIN.texCoord;
#else
	OUT.Color = color;
#endif
	OUT.position = mul(modelViewProj, position);
	OUT.texCoord = texCoord;
	
	return OUT;
}

const float	  floatpi	  = 1.5707963267948966192313216916398;
const float			pi	  = 3.1415926535897932384626433832795;

float l(float x)
{ 
	if (x==0.0)
		return pi*floatpi;
	else
		return sin(x*floatpi)*sin(x*pi)/(x*x);
}

float4 lanczos12(float2 texture_size, float2 texCoord, COMPAT_Texture2D(decal))
{
	float2 ps = float2(0.999/texture_size.x, 0.999/texture_size.y);

	float2 crd[4][4];  float3 pix[4][4];

	float2 dx = float2(ps.x,0.0); float2 dy = float2(0.0,ps.y);

	float2 pixcoord  = texCoord/ps;
	float2 fract	  = frac(pixcoord);
	float2 coord0	 = texCoord-(fract)*ps;


	// calculating coordinates for 16 texels
	crd[0][0]=coord0-ps;	 crd[1][0]=crd[0][0]+dx; 
	crd[2][0]=crd[1][0]+dx; 
	crd[0][1]=crd[0][0]+dy; crd[1][1]=crd[0][1]+dx; 
	crd[2][1]=crd[1][1]+dx; crd[3][1]=crd[2][1]+dx;
	crd[0][2]=crd[0][1]+dy; crd[1][2]=crd[0][2]+dx; 
	crd[2][2]=crd[1][2]+dx; crd[3][2]=crd[2][2]+dx;
	crd[0][3]=crd[0][2]+dy; crd[1][3]=crd[0][3]+dx; 
	crd[2][3]=crd[1][3]+dx; 


	// calculating texel weights
	float a,b,c,d,p,q,r,s;

	a = l(1+fract.x); 
	b = l(  fract.x); 
	c = l(1-fract.x); 
	d = l(2-fract.x);

	p = l(1+fract.y); 
	q = l(  fract.y); 
	r = l(1-fract.y); 
	s = l(2-fract.y);


	// reading the texels
	pix[1][0] = COMPAT_SamplePoint(decal, crd[1][0]).xyz;
	pix[2][0] = COMPAT_SamplePoint(decal, crd[2][0]).xyz;
	pix[0][1] = COMPAT_SamplePoint(decal, crd[0][1]).xyz;
	pix[1][1] = COMPAT_SamplePoint(decal, crd[1][1]).xyz;
	pix[2][1] = COMPAT_SamplePoint(decal, crd[2][1]).xyz;
	pix[3][1] = COMPAT_SamplePoint(decal, crd[3][1]).xyz;
	pix[0][2] = COMPAT_SamplePoint(decal, crd[0][2]).xyz;
	pix[1][2] = COMPAT_SamplePoint(decal, crd[1][2]).xyz;
	pix[2][2] = COMPAT_SamplePoint(decal, crd[2][2]).xyz;
	pix[3][2] = COMPAT_SamplePoint(decal, crd[3][2]).xyz;
	pix[1][3] = COMPAT_SamplePoint(decal, crd[1][3]).xyz;
	pix[2][3] = COMPAT_SamplePoint(decal, crd[2][3]).xyz;


	// applying weights
	pix[1][0] = (pix[1][0]*b+pix[2][0]*c)*p;
	pix[0][1] = (pix[0][1]*a+pix[1][1]*b+pix[2][1]*c+pix[3][1]*d)*q;
	pix[0][2] = (pix[0][2]*a+pix[1][2]*b+pix[2][2]*c+pix[3][2]*d)*r;
	pix[1][3] = (pix[1][3]*b+pix[2][3]*c)*s;


	// final sum and weight normalization
	return float4((pix[1][0]+pix[0][1]+pix[0][2]+pix[1][3])/((a+b+c+d)*(p+q+r+s)-(a+d)*(p+s)),1);
}

float4 main_fragment(COMPAT_IN_FRAGMENT) : COMPAT_Output
{
	return lanczos12(COMPAT_texture_size, VOUT.texCoord, decal);
}
COMPAT_END