|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- -- GLSL.Vert --
-
- #version 120
-
- #if defined GL_ES
- precision highp float;
- #endif
-
- uniform mat4 u_ZoomSettings;
- uniform vec4 u_TexelSize;
- uniform vec4 u_ScreenSize;
-
- attribute vec2 a_TexCoord;
- attribute vec2 a_Vertex;
-
- varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;
-
- void main(void)
- {
- gl_Position = vec4(a_Vertex, 0.0, 1.0);
- /* Center point in [-.5,.5], apply zoom and translation
- * transformation, and go back to texture coordinates
- * in [0,1]. That's the ideal point we would like to
- * 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. */
- 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]);
- 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. */
- v_IndexX = v_CenterX * u_ScreenSize.z - offsets.zwzw;
- v_IndexY = v_CenterY * u_ScreenSize.w - offsets.zwwz;
- }
-
- -- GLSL.Frag --
-
- #version 120
-
- #if defined GL_ES
- precision highp float;
- #endif
-
- uniform vec4 u_TexelSize;
- uniform sampler2D u_Texture;
-
- varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;
-
- void main(void)
- {
- vec4 v05 = vec4(0.5, 0.5, 0.5, 0.5);
- vec4 rx, ry, t0, dx, dy, dd;
- /* Get a pixel coordinate from each slice into rx & ry */
- rx = u_TexelSize.x + u_TexelSize.z * floor(v_IndexX);
- ry = u_TexelSize.y + u_TexelSize.w * floor(v_IndexY);
- /* Compute inverse distance to expected pixel in dd,
- * and put zero if we fall outside the texture. */
- t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);
- dx = rx - v_CenterX;
- dy = ry - v_CenterY;
- #if 0
- vec4 dd = t0 * (abs(dx) + abs(dy));
- vec4 dd = t0 / (0.001 + sqrt((dx * dx) + (dy * dy)));
- #endif
- 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
- # if 0
- /* XXX: disabled until we can autodetect i915 */
- /* t1.x <-- dd.x > dd.y */
- /* t1.y <-- dd.z > dd.w */
- vec2 t1 = step(dd.xz, dd.yw);
- /* ret.x <-- max(rx.x, rx.y) wrt. t1.x */
- /* ret.y <-- max(rx.z, rx.w) wrt. t1.y */
- /* ret.z <-- max(ry.x, ry.y) wrt. t1.x */
- /* ret.w <-- max(ry.z, ry.w) wrt. t1.y */
- vec4 ret = mix(vec4(rx.xz, ry.xz),
- vec4(rx.yw, ry.yw), t1.xyxy);
- /* dd.x <-- max(dd.x, dd.y) */
- /* dd.z <-- max(dd.z, dd.w) */
- dd.xy = mix(dd.xz, dd.yw, t1);
- /* t2 <-- dd.x > dd.z */
- float t2 = step(dd.x, dd.y);
- /* ret.x <-- max(ret.x, ret.y); */
- /* ret.y <-- max(ret.z, ret.w); */
- ret.xy = mix(ret.xz, ret.yw, t2);
- # else
- /* Fallback for i915 cards -- the trick to reduce the
- * number of operations is to compute both step(a,b)
- * and step(b,a) and hope that their sum is 1. This is
- * almost always the case, and when it isn't we can
- * afford to have a few wrong pixels. However, a real
- * problem is when panning the image, because half the
- * screen is likely to flicker. To avoid this problem,
- * we cheat a little (see m_translate comment above). */
- vec4 t1 = step(dd.xzyw, dd.ywxz);
- vec4 ret = vec4(rx.xz, ry.xz) * t1.zwzw
- + vec4(rx.yw, ry.yw) * t1.xyxy;
- dd.xy = dd.xz * t1.zw + dd.yw * t1.xy;
- vec2 t2 = step(dd.xy, dd.yx);
- ret.xy = ret.xz * t2.yy + ret.yw * t2.xx;
- # endif
- /* Nearest neighbour */
- gl_FragColor = texture2D(u_Texture, ret.xy);
- #else
- /* Alternate version: some kind of linear interpolation */
- vec4 p0 = texture2D(u_Texture, vec2(rx.x, ry.x));
- vec4 p1 = texture2D(u_Texture, vec2(rx.y, ry.y));
- vec4 p2 = texture2D(u_Texture, vec2(rx.z, ry.z));
- vec4 p3 = texture2D(u_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
- }
-
- -- HLSL.Vert --
-
- void main(float2 a_Vertex : POSITION,
- float2 a_TexCoord : TEXCOORD0,
- uniform float4x4 u_ZoomSettings,
- uniform float4 u_TexelSize,
- uniform float4 u_ScreenSize,
- out float4 out_Position : POSITION0,
- out float4 v_CenterX : TEXCOORD0,
- out float4 v_CenterY : TEXCOORD1,
- out float4 v_IndexX : TEXCOORD2,
- out float4 v_IndexY : TEXCOORD3)
- {
- out_Position = float4(a_Vertex, 0.0, 1.0);
- float4 offsets = float4(0.5, -0.5, 0.015625, -0.015625);
- float4 zoomscale = float4(u_ZoomSettings[2][0],
- u_ZoomSettings[2][1],
- u_ZoomSettings[2][2],
- u_ZoomSettings[2][3]);
- float4 zoomtx = float4(u_ZoomSettings[0][0],
- u_ZoomSettings[0][1],
- u_ZoomSettings[0][2],
- u_ZoomSettings[0][3]);
- float4 zoomty = float4(u_ZoomSettings[1][0],
- u_ZoomSettings[1][1],
- u_ZoomSettings[1][2],
- u_ZoomSettings[1][3]);
- v_CenterX = zoomscale * a_TexCoord.x + zoomtx
- + offsets.xyxy * u_TexelSize.x;
- v_CenterY = zoomscale * a_TexCoord.y - zoomty
- + offsets.xyyx * u_TexelSize.y;
- v_IndexX = v_CenterX * u_ScreenSize.z - offsets.zwzw;
- v_IndexY = v_CenterY * u_ScreenSize.w - offsets.zwwz;
- }
-
- -- HLSL.Frag --
-
- void main(in float4 v_CenterX : TEXCOORD0,
- in float4 v_CenterY : TEXCOORD1,
- in float4 v_IndexX : TEXCOORD2,
- in float4 v_IndexY : TEXCOORD3,
- uniform float4 u_TexelSize,
- uniform sampler2D u_Texture,
- out float4 out_FragColor : COLOR)
- {
- float4 v05 = float4(0.5, 0.5, 0.5, 0.5);
- float4 rx, ry, t0, dx, dy, dd;
- rx = u_TexelSize.x + u_TexelSize.z * floor(v_IndexX);
- ry = u_TexelSize.y + u_TexelSize.w * floor(v_IndexY);
- t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);
- dx = rx - v_CenterX;
- dy = ry - v_CenterY;
- dd = t0 / (0.000001 + (dx * dx) + (dy * dy));
- ry = ry * 0.25 + float4(0.0, 0.25, 0.5, 0.75);
- float2 t1 = step(dd.xz, dd.yw);
- float4 ret = lerp(float4(rx.xz, ry.xz),
- float4(rx.yw, ry.yw), t1.xyxy);
- dd.xy = lerp(dd.xz, dd.yw, t1);
- float t2 = step(dd.x, dd.y);
- ret.xy = lerp(ret.xz, ret.yw, t2);
- out_FragColor = tex2D(u_Texture, ret.xy);
- }
-
|