1#version 130 2 3#define fetch_offset(offset, one_x) \ 4 COMPAT_TEXTURE(Source, vTexCoord + vec2((offset) * (one_x), 0.0)).xyz 5 6#if defined(VERTEX) 7 8#if __VERSION__ >= 130 9#define COMPAT_VARYING out 10#define COMPAT_ATTRIBUTE in 11#define COMPAT_TEXTURE texture 12#else 13#define COMPAT_VARYING varying 14#define COMPAT_ATTRIBUTE attribute 15#define COMPAT_TEXTURE texture2D 16#endif 17 18#ifdef GL_ES 19#define COMPAT_PRECISION mediump 20#else 21#define COMPAT_PRECISION 22#endif 23 24COMPAT_ATTRIBUTE vec4 VertexCoord; 25COMPAT_ATTRIBUTE vec4 COLOR; 26COMPAT_ATTRIBUTE vec4 TexCoord; 27COMPAT_VARYING vec4 COL0; 28COMPAT_VARYING vec4 TEX0; 29 30uniform mat4 MVPMatrix; 31uniform COMPAT_PRECISION int FrameDirection; 32uniform COMPAT_PRECISION int FrameCount; 33uniform COMPAT_PRECISION vec2 OutputSize; 34uniform COMPAT_PRECISION vec2 TextureSize; 35uniform COMPAT_PRECISION vec2 InputSize; 36 37// vertex compatibility #defines 38#define vTexCoord TEX0.xy 39#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 40#define outsize vec4(OutputSize, 1.0 / OutputSize) 41 42void main() 43{ 44 gl_Position = MVPMatrix * VertexCoord; 45 COL0 = COLOR; 46 TEX0.xy = TexCoord.xy - vec2(0.5 / SourceSize.x, 0.0); // Compensate for decimate-by-2. 47} 48 49#elif defined(FRAGMENT) 50 51#ifdef GL_ES 52#ifdef GL_FRAGMENT_PRECISION_HIGH 53precision highp float; 54#else 55precision mediump float; 56#endif 57#define COMPAT_PRECISION mediump 58#else 59#define COMPAT_PRECISION 60#endif 61 62#if __VERSION__ >= 130 63#define COMPAT_VARYING in 64#define COMPAT_TEXTURE texture 65out COMPAT_PRECISION vec4 FragColor; 66#else 67#define COMPAT_VARYING varying 68#define FragColor gl_FragColor 69#define COMPAT_TEXTURE texture2D 70#endif 71 72uniform COMPAT_PRECISION int FrameDirection; 73uniform COMPAT_PRECISION int FrameCount; 74uniform COMPAT_PRECISION vec2 OutputSize; 75uniform COMPAT_PRECISION vec2 TextureSize; 76uniform COMPAT_PRECISION vec2 InputSize; 77uniform sampler2D Texture; 78COMPAT_VARYING vec4 TEX0; 79 80// fragment compatibility #defines 81#define Source Texture 82#define vTexCoord TEX0.xy 83 84#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 85#define outsize vec4(OutputSize, 1.0 / OutputSize) 86 87// begin ntsc-rgbyuv 88const mat3 yiq2rgb_mat = mat3( 89 1.0, 0.956, 0.6210, 90 1.0, -0.2720, -0.6474, 91 1.0, -1.1060, 1.7046); 92 93vec3 yiq2rgb(vec3 yiq) 94{ 95 return yiq * yiq2rgb_mat; 96} 97 98const mat3 yiq_mat = mat3( 99 0.2989, 0.5870, 0.1140, 100 0.5959, -0.2744, -0.3216, 101 0.2115, -0.5229, 0.3114 102); 103 104vec3 rgb2yiq(vec3 col) 105{ 106 return col * yiq_mat; 107} 108// end ntsc-rgbyuv 109 110// begin ntsc-decode-filter-3phase 111#if __VERSION__ <= 130 112float luma_filter1 = -0.000012020; 113float luma_filter2 = -0.000022146; 114float luma_filter3 = -0.000013155; 115float luma_filter4 = -0.000012020; 116float luma_filter5 = -0.000049979; 117float luma_filter6 = -0.000113940; 118float luma_filter7 = -0.000122150; 119float luma_filter8 = -0.000005612; 120float luma_filter9 = 0.000170516; 121float luma_filter10 = 0.000237199; 122float luma_filter11 = 0.000169640; 123float luma_filter12 = 0.000285688; 124float luma_filter13 = 0.000984574; 125float luma_filter14 = 0.002018683; 126float luma_filter15 = 0.002002275; 127float luma_filter16 = -0.000909882; 128float luma_filter17 = -0.007049081; 129float luma_filter18 = -0.013222860; 130float luma_filter19 = -0.012606931; 131float luma_filter20 = 0.002460860; 132float luma_filter21 = 0.035868225; 133float luma_filter22 = 0.084016453; 134float luma_filter23 = 0.135563500; 135float luma_filter24 = 0.175261268; 136float luma_filter25 = 0.190176552; 137 138float chroma_filter1 = -0.000118847; 139float chroma_filter2 = -0.000271306; 140float chroma_filter3 = -0.000502642; 141float chroma_filter4 = -0.000930833; 142float chroma_filter5 = -0.001451013; 143float chroma_filter6 = -0.002064744; 144float chroma_filter7 = -0.002700432; 145float chroma_filter8 = -0.003241276; 146float chroma_filter9 = -0.003524948; 147float chroma_filter10 = -0.003350284; 148float chroma_filter11 = -0.002491729; 149float chroma_filter12 = -0.000721149; 150float chroma_filter13 = 0.002164659; 151float chroma_filter14 = 0.006313635; 152float chroma_filter15 = 0.011789103; 153float chroma_filter16 = 0.018545660; 154float chroma_filter17 = 0.026414396; 155float chroma_filter18 = 0.035100710; 156float chroma_filter19 = 0.044196567; 157float chroma_filter20 = 0.053207202; 158float chroma_filter21 = 0.061590275; 159float chroma_filter22 = 0.068803602; 160float chroma_filter23 = 0.074356193; 161float chroma_filter24 = 0.077856564; 162float chroma_filter25 = 0.079052396; 163#else 164#define TAPS 24 165const float luma_filter[TAPS + 1] = float[TAPS + 1]( 166 -0.000012020, 167 -0.000022146, 168 -0.000013155, 169 -0.000012020, 170 -0.000049979, 171 -0.000113940, 172 -0.000122150, 173 -0.000005612, 174 0.000170516, 175 0.000237199, 176 0.000169640, 177 0.000285688, 178 0.000984574, 179 0.002018683, 180 0.002002275, 181 -0.000909882, 182 -0.007049081, 183 -0.013222860, 184 -0.012606931, 185 0.002460860, 186 0.035868225, 187 0.084016453, 188 0.135563500, 189 0.175261268, 190 0.190176552); 191 192const float chroma_filter[TAPS + 1] = float[TAPS + 1]( 193 -0.000118847, 194 -0.000271306, 195 -0.000502642, 196 -0.000930833, 197 -0.001451013, 198 -0.002064744, 199 -0.002700432, 200 -0.003241276, 201 -0.003524948, 202 -0.003350284, 203 -0.002491729, 204 -0.000721149, 205 0.002164659, 206 0.006313635, 207 0.011789103, 208 0.018545660, 209 0.026414396, 210 0.035100710, 211 0.044196567, 212 0.053207202, 213 0.061590275, 214 0.068803602, 215 0.074356193, 216 0.077856564, 217 0.079052396); 218#endif 219// end ntsc-decode-filter-3phase 220 221void main() 222{ 223// begin ntsc-pass2-decode 224 float one_x = 1.0 / SourceSize.x; 225 vec3 signal = vec3(0.0); 226#if __VERSION__ <= 130 227 float offset; 228 vec3 sums; 229 230 #define macro_loopz(c) offset = float(c) - 1.0; \ 231 sums = fetch_offset(offset - 24., one_x) + fetch_offset(24. - offset, one_x); \ 232 signal += sums * vec3(luma_filter##c, chroma_filter##c, chroma_filter##c); 233 234 // unrolling the loopz 235 macro_loopz(1) 236 macro_loopz(2) 237 macro_loopz(3) 238 macro_loopz(4) 239 macro_loopz(5) 240 macro_loopz(6) 241 macro_loopz(7) 242 macro_loopz(8) 243 macro_loopz(9) 244 macro_loopz(10) 245 macro_loopz(11) 246 macro_loopz(12) 247 macro_loopz(13) 248 macro_loopz(14) 249 macro_loopz(15) 250 macro_loopz(16) 251 macro_loopz(17) 252 macro_loopz(18) 253 macro_loopz(19) 254 macro_loopz(20) 255 macro_loopz(21) 256 macro_loopz(22) 257 macro_loopz(23) 258 macro_loopz(24) 259 260 signal += COMPAT_TEXTURE(Texture, TEX0.xy).xyz * 261 vec3(luma_filter25, chroma_filter25, chroma_filter25); 262#else 263 for (int i = 0; i < TAPS; i++) 264 { 265 float offset = float(i); 266 267 vec3 sums = fetch_offset(offset - float(TAPS), one_x) + 268 fetch_offset(float(TAPS) - offset, one_x); 269 270 signal += sums * vec3(luma_filter[i], chroma_filter[i], chroma_filter[i]); 271 } 272 signal += COMPAT_TEXTURE(Source, vTexCoord).xyz * 273 vec3(luma_filter[TAPS], chroma_filter[TAPS], chroma_filter[TAPS]); 274#endif 275// end ntsc-pass2-decode 276 vec3 rgb = yiq2rgb(signal); 277 FragColor = vec4(rgb, 1.0); 278} 279#endif 280