| @@ -394,8 +394,7 @@ public: | |||
| "attribute vec2 a_TexCoord;" | |||
| "attribute vec2 a_Vertex;" | |||
| "" | |||
| "varying vec2 A0, A1, A2, A3;" | |||
| "varying vec2 B0, B1, B2, B3;" | |||
| "varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;" | |||
| "" | |||
| "void main(void)" | |||
| "{" | |||
| @@ -406,26 +405,30 @@ public: | |||
| * compute the value for. Then add or remove half the | |||
| * size of a texel: the distance from this new point to | |||
| * the final point will be our error. */ | |||
| " A0 = a_TexCoord * u_ZoomSettings[0][2]" | |||
| " + vec2(u_ZoomSettings[0][0], -u_ZoomSettings[0][1])" | |||
| " + 0.5 * u_TexelSize.xy;" | |||
| " A1 = a_TexCoord * u_ZoomSettings[1][2]" | |||
| " + vec2(u_ZoomSettings[1][0], -u_ZoomSettings[1][1])" | |||
| " + -0.5 * u_TexelSize.xy;" | |||
| " A2 = a_TexCoord * u_ZoomSettings[2][2]" | |||
| " + vec2(u_ZoomSettings[2][0], -u_ZoomSettings[2][1])" | |||
| " + vec2(0.5, -0.5) * u_TexelSize.xy;" | |||
| " A3 = a_TexCoord * u_ZoomSettings[3][2]" | |||
| " + vec2(u_ZoomSettings[3][0], -u_ZoomSettings[3][1])" | |||
| " + vec2(-0.5, 0.5) * u_TexelSize.xy;" | |||
| " vec4 offsets = vec4(0.5, -0.5, 0.015625, -0.015625);" | |||
| " vec4 zoomscale = vec4(u_ZoomSettings[0][2]," | |||
| " u_ZoomSettings[1][2]," | |||
| " u_ZoomSettings[2][2]," | |||
| " u_ZoomSettings[3][2]);" | |||
| " vec4 zoomtx = vec4(u_ZoomSettings[0][0]," | |||
| " u_ZoomSettings[1][0]," | |||
| " u_ZoomSettings[2][0]," | |||
| " u_ZoomSettings[3][0]);" | |||
| " vec4 zoomty = vec4(u_ZoomSettings[0][1]," | |||
| " u_ZoomSettings[1][1]," | |||
| " u_ZoomSettings[2][1]," | |||
| " u_ZoomSettings[3][1]);" | |||
| /* Pass all this to the fragment shader */ | |||
| " v_CenterX = zoomscale * a_TexCoord.x + zoomtx" | |||
| " + offsets.xyxy * u_TexelSize.x;" | |||
| " v_CenterY = zoomscale * a_TexCoord.y - zoomty" | |||
| " + offsets.xyyx * u_TexelSize.y;" | |||
| /* Precompute the multiple of one texel where our ideal | |||
| * point lies. The fragment shader will call floor() on | |||
| * this value. We add or remove a slight offset to avoid | |||
| * rounding issues at the image's edges. */ | |||
| " B0 = (A0 * u_TexelSize.zw + vec2(-0.015625, -0.015625));" | |||
| " B1 = (A1 * u_TexelSize.zw + vec2( 0.015625, 0.015625));" | |||
| " B2 = (A2 * u_TexelSize.zw + vec2(-0.015625, 0.015625));" | |||
| " B3 = (A3 * u_TexelSize.zw + vec2( 0.015625, -0.015625));" | |||
| " v_IndexX = v_CenterX * u_TexelSize.z - offsets.zwzw;" | |||
| " v_IndexY = v_CenterY * u_TexelSize.w - offsets.zwwz;" | |||
| "}", | |||
| #if !defined HAVE_GLES_2X | |||
| @@ -437,77 +440,46 @@ public: | |||
| "uniform vec4 u_TexelSize;" | |||
| "uniform sampler2D in_Texture;" | |||
| "" | |||
| "varying vec2 A0, A1, A2, A3;" | |||
| "varying vec2 B0, B1, B2, B3;" | |||
| "" | |||
| "vec2 v05 = vec2(0.5, 0.5);" | |||
| "" | |||
| "float mylen(vec2 p)" | |||
| "{" | |||
| " p *= u_TexelSize.zw;" /* Correct for aspect ratio */ | |||
| //" return 0.001 + abs(p.x) + abs(p.y);" | |||
| //" return 0.1 + length(p);" | |||
| " vec2 q = p * p;" | |||
| " return 0.01 + q.x + q.y;" | |||
| "}" | |||
| "" | |||
| /* Get the coordinate of the nearest point in slice 0 in xy, | |||
| * and the squared distance to that point in z. | |||
| * return value has the 0.25 Y scaling. */ | |||
| "vec3 nearest0()" | |||
| "{" | |||
| " vec2 r = u_TexelSize.xy * (1.0 + 2.0 * floor(B0));" | |||
| " vec2 t = step(abs(r - v05), v05);" | |||
| " float l = t.x * t.y / mylen(r - A0);" | |||
| " return vec3(r * vec2(1.0, 0.25), l);" | |||
| "}" | |||
| "" | |||
| "vec3 nearest1()" | |||
| "{" | |||
| " vec2 r = u_TexelSize.xy * (1.0 + 2.0 * floor(B1));" | |||
| " vec2 t = step(abs(r - v05), v05);" | |||
| " float l = t.x * t.y / mylen(r - A1);" | |||
| " return vec3(r * vec2(1.0, 0.25) + vec2(0.0, 0.25), l);" | |||
| "}" | |||
| "" | |||
| "vec3 nearest2()" | |||
| "{" | |||
| " vec2 r = u_TexelSize.xy * (1.0 + 2.0 * floor(B2));" | |||
| " vec2 t = step(abs(r - v05), v05);" | |||
| " float l = t.x * t.y / mylen(r - A2);" | |||
| " return vec3(r * vec2(1.0, 0.25) + vec2(0.0, 0.50), l);" | |||
| "}" | |||
| "" | |||
| "vec3 nearest3()" | |||
| "{" | |||
| " vec2 r = u_TexelSize.xy * (1.0 + 2.0 * floor(B3));" | |||
| " vec2 t = step(abs(r - v05), v05);" | |||
| " float l = t.x * t.y / mylen(r - A3);" | |||
| " return vec3(r * vec2(1.0, 0.25) + vec2(0.0, 0.75), l);" | |||
| "}" | |||
| "varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;" | |||
| "" | |||
| "void main(void)" | |||
| "{" | |||
| /* Get a pixel coordinate from each slice */ | |||
| " vec3 k0 = nearest0();" | |||
| " vec3 k1 = nearest1();" | |||
| " vec3 k2 = nearest2();" | |||
| " vec3 k3 = nearest3();" | |||
| /* Get the nearest pixel */ | |||
| " float t01 = step(k0.z, k1.z);" | |||
| " k0 = mix(k0, k1, t01);" | |||
| " float t23 = step(k2.z, k3.z);" | |||
| " k2 = mix(k2, k3, t23);" | |||
| " float t02 = step(k0.z, k2.z);" | |||
| " k0 = mix(k0, k2, t02);" | |||
| " gl_FragColor = texture2D(in_Texture, k0.xy);" | |||
| /* Get a pixel coordinate from each slice into rx & ry */ | |||
| " vec4 rx = u_TexelSize.x * (1.0 + 2.0 * floor(v_IndexX));" | |||
| " vec4 ry = u_TexelSize.y * (1.0 + 2.0 * floor(v_IndexY));" | |||
| /* Compute distance to expected pixel in dd */ | |||
| " vec4 v05 = vec4(0.5, 0.5, 0.5, 0.5);" | |||
| " vec4 t0 = step(abs(rx - v05), v05)" | |||
| " * step(abs(ry - v05), v05);" | |||
| " vec4 dx = rx - v_CenterX;" | |||
| " vec4 dy = ry - v_CenterY;" | |||
| //" vec4 dd = t0 * (abs(dx) + abs(dy));" | |||
| //" vec4 dd = t0 / (0.001 + sqrt((dx * dx) + (dy * dy)));" | |||
| " vec4 dd = t0 / (0.000001 + (dx * dx) + (dy * dy));" | |||
| /* Modify Y coordinate to select proper quarter. */ | |||
| " ry = ry * 0.25 + vec4(0.0, 0.25, 0.5, 0.75);" | |||
| "" | |||
| #if 1 | |||
| /* Put min(.x,.y) in .x and min(.z,.w) in .z */ | |||
| " vec4 t1 = step(dd, dd.yyww);" | |||
| " rx = mix(rx, rx.yyww, t1);" | |||
| " ry = mix(ry, ry.yyww, t1);" | |||
| " dd = mix(dd, dd.yyww, t1);" | |||
| /* Put min(x,z) in x */ | |||
| " vec4 t2 = step(dd, dd.zzzz);" | |||
| " rx = mix(rx, rx.zzzz, t2);" | |||
| " ry = mix(ry, ry.zzzz, t2);" | |||
| /* Nearest neighbour */ | |||
| " gl_FragColor = texture2D(in_Texture, vec2(rx.x, ry.x));" | |||
| #else | |||
| /* Alternate version: some kind of linear interpolation */ | |||
| // " vec4 p0 = texture2D(in_Texture, k0.xy);" | |||
| // " vec4 p1 = texture2D(in_Texture, k1.xy);" | |||
| // " vec4 p2 = texture2D(in_Texture, k2.xy);" | |||
| // " vec4 p3 = texture2D(in_Texture, k3.xy);" | |||
| // " gl_FragColor = 1.0 / (k0.z + k1.z + k2.z + k3.z)" | |||
| // " * (k0.z * p0 + k1.z * p1 + k2.z * p2 + k3.z * p3);" | |||
| " vec4 p0 = texture2D(in_Texture, vec2(rx.x, ry.x));" | |||
| " vec4 p1 = texture2D(in_Texture, vec2(rx.y, ry.y));" | |||
| " vec4 p2 = texture2D(in_Texture, vec2(rx.z, ry.z));" | |||
| " vec4 p3 = texture2D(in_Texture, vec2(rx.w, ry.w));" | |||
| " gl_FragColor = 1.0 / (dd.x + dd.y + dd.z + dd.w)" | |||
| " * (dd.x * p0 + dd.y * p1 + dd.z * p2 + dd.w * p3);" | |||
| #endif | |||
| "}" | |||
| #else | |||
| "void main(float4 in_Position : POSITION," | |||