// sphericalprocess.frag
// (c) LLib Source Code Trust. All rights reserved.
//

#version 120

// Uniforms
// ScaleX, ScaleY, Width, Height
uniform vec4 v4fUniform0;
// Rotation matrix values
uniform vec4 v4fUniform1;
uniform vec4 v4fUniform2;
uniform vec4 v4fUniform3;
uniform sampler2D texUnit0;
uniform float fUniformAlpha;

// Inputs from vertex shader
varying vec2 v2fTexCoord;

// Params from uniforms
vec4 v4fParameters = v4fUniform0;
// 3x3 transposed version of the original matrix from the source. This is because an OpenGL matrix created from vectors is column-major
mat3 m3fRotationTransposed = mat3(vec3(v4fUniform1), vec3(v4fUniform2), vec3(v4fUniform3));

// Constants
const float M_PI = 3.14159265f;
const float M_2PI = 6.28318530f;

// Utility functions

vec3 ComputeEyeVector(in vec2 v2fPosition)
{
   vec3 v3fEveVector;
   v3fEveVector.x = ((((2.0f * v2fPosition.x) / v4fParameters.z) - 1.0f) / v4fParameters.x);
   v3fEveVector.y = ((((2.0f * v2fPosition.y) / v4fParameters.w) - 1.0f) / v4fParameters.y);
   v3fEveVector.z = 1.0f;
   vec3 v3fOut = normalize(v3fEveVector);
   return v3fOut;
}

vec2 ComputeSphericalCoord(in vec3 v3fRotated)
{
   vec2 v2fOut;
   v2fOut.x = ((atan(v3fRotated.x, v3fRotated.z) / M_2PI) + 0.5f);
   v2fOut.y = ((asin(v3fRotated.y) / M_PI) + 0.5f);
   return v2fOut;
}


void main()
{
   vec3 v3fEyeVector = ComputeEyeVector(v2fTexCoord * v4fParameters.zw);
   vec3 v3fRotated = vec3(m3fRotationTransposed * v3fEyeVector); // Matrix(transposed) * Vector to effectively get Vector * Matrix
   vec2 v2fUV = ComputeSphericalCoord(v3fRotated);
   vec2 v2fRemainder = vec2(mod(v2fUV.x, 1.0f), mod(v2fUV.y, 1.0f));
   vec4 v4fColor = texture2D(texUnit0, v2fRemainder);
   gl_FragColor = vec4(v4fColor.rgb, v4fColor.a * fUniformAlpha);
}
