You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

197 lines
7.0 KiB

  1. [vert.glsl]
  2. #version 120
  3. #if defined GL_ES
  4. precision highp float;
  5. #endif
  6. uniform mat4 u_ZoomSettings;
  7. uniform vec4 u_TexelSize;
  8. uniform vec4 u_ScreenSize;
  9. attribute vec2 a_TexCoord;
  10. attribute vec2 a_Vertex;
  11. varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;
  12. void main(void)
  13. {
  14. gl_Position = vec4(a_Vertex, 0.0, 1.0);
  15. /* Center point in [-.5,.5], apply zoom and translation
  16. * transformation, and go back to texture coordinates
  17. * in [0,1]. That's the ideal point we would like to
  18. * compute the value for. Then add or remove half the
  19. * size of a texel: the distance from this new point to
  20. * the final point will be our error. */
  21. vec4 offsets = vec4(0.5, -0.5, 0.015625, -0.015625);
  22. vec4 zoomscale = vec4(u_ZoomSettings[0][2],
  23. u_ZoomSettings[1][2],
  24. u_ZoomSettings[2][2],
  25. u_ZoomSettings[3][2]);
  26. vec4 zoomtx = vec4(u_ZoomSettings[0][0],
  27. u_ZoomSettings[1][0],
  28. u_ZoomSettings[2][0],
  29. u_ZoomSettings[3][0]);
  30. vec4 zoomty = vec4(u_ZoomSettings[0][1],
  31. u_ZoomSettings[1][1],
  32. u_ZoomSettings[2][1],
  33. u_ZoomSettings[3][1]);
  34. v_CenterX = zoomscale * a_TexCoord.x + zoomtx
  35. + offsets.xyxy * u_TexelSize.x;
  36. v_CenterY = zoomscale * a_TexCoord.y - zoomty
  37. + offsets.xyyx * u_TexelSize.y;
  38. /* Precompute the multiple of one texel where our ideal
  39. * point lies. The fragment shader will call floor() on
  40. * this value. We add or remove a slight offset to avoid
  41. * rounding issues at the image's edges. */
  42. v_IndexX = v_CenterX * u_ScreenSize.z - offsets.zwzw;
  43. v_IndexY = v_CenterY * u_ScreenSize.w - offsets.zwwz;
  44. }
  45. [frag.glsl]
  46. #version 120
  47. #if defined GL_ES
  48. precision highp float;
  49. #endif
  50. uniform vec4 u_TexelSize;
  51. uniform sampler2D u_Texture;
  52. varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;
  53. void main(void)
  54. {
  55. vec4 v05 = vec4(0.5, 0.5, 0.5, 0.5);
  56. vec4 rx, ry, t0, dx, dy, dd;
  57. /* Get a pixel coordinate from each slice into rx & ry */
  58. rx = u_TexelSize.x + u_TexelSize.z * floor(v_IndexX);
  59. ry = u_TexelSize.y + u_TexelSize.w * floor(v_IndexY);
  60. /* Compute inverse distance to expected pixel in dd,
  61. * and put zero if we fall outside the texture. */
  62. t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);
  63. dx = rx - v_CenterX;
  64. dy = ry - v_CenterY;
  65. #if 0
  66. vec4 dd = t0 * (abs(dx) + abs(dy));
  67. vec4 dd = t0 / (0.001 + sqrt((dx * dx) + (dy * dy)));
  68. #endif
  69. dd = t0 / (0.000001 + (dx * dx) + (dy * dy));
  70. /* Modify Y coordinate to select proper quarter. */
  71. ry = ry * 0.25 + vec4(0.0, 0.25, 0.5, 0.75);
  72. #if 1
  73. # if 0
  74. /* XXX: disabled until we can autodetect i915 */
  75. /* t1.x <-- dd.x > dd.y */
  76. /* t1.y <-- dd.z > dd.w */
  77. vec2 t1 = step(dd.xz, dd.yw);
  78. /* ret.x <-- max(rx.x, rx.y) wrt. t1.x */
  79. /* ret.y <-- max(rx.z, rx.w) wrt. t1.y */
  80. /* ret.z <-- max(ry.x, ry.y) wrt. t1.x */
  81. /* ret.w <-- max(ry.z, ry.w) wrt. t1.y */
  82. vec4 ret = mix(vec4(rx.xz, ry.xz),
  83. vec4(rx.yw, ry.yw), t1.xyxy);
  84. /* dd.x <-- max(dd.x, dd.y) */
  85. /* dd.z <-- max(dd.z, dd.w) */
  86. dd.xy = mix(dd.xz, dd.yw, t1);
  87. /* t2 <-- dd.x > dd.z */
  88. float t2 = step(dd.x, dd.y);
  89. /* ret.x <-- max(ret.x, ret.y); */
  90. /* ret.y <-- max(ret.z, ret.w); */
  91. ret.xy = mix(ret.xz, ret.yw, t2);
  92. # else
  93. /* Fallback for i915 cards -- the trick to reduce the
  94. * number of operations is to compute both step(a,b)
  95. * and step(b,a) and hope that their sum is 1. This is
  96. * almost always the case, and when it isn't we can
  97. * afford to have a few wrong pixels. However, a real
  98. * problem is when panning the image, because half the
  99. * screen is likely to flicker. To avoid this problem,
  100. * we cheat a little (see m_translate comment above). */
  101. vec4 t1 = step(dd.xzyw, dd.ywxz);
  102. vec4 ret = vec4(rx.xz, ry.xz) * t1.zwzw
  103. + vec4(rx.yw, ry.yw) * t1.xyxy;
  104. dd.xy = dd.xz * t1.zw + dd.yw * t1.xy;
  105. vec2 t2 = step(dd.xy, dd.yx);
  106. ret.xy = ret.xz * t2.yy + ret.yw * t2.xx;
  107. # endif
  108. /* Nearest neighbour */
  109. gl_FragColor = texture2D(u_Texture, ret.xy);
  110. #else
  111. /* Alternate version: some kind of linear interpolation */
  112. vec4 p0 = texture2D(u_Texture, vec2(rx.x, ry.x));
  113. vec4 p1 = texture2D(u_Texture, vec2(rx.y, ry.y));
  114. vec4 p2 = texture2D(u_Texture, vec2(rx.z, ry.z));
  115. vec4 p3 = texture2D(u_Texture, vec2(rx.w, ry.w));
  116. gl_FragColor = 1.0 / (dd.x + dd.y + dd.z + dd.w)
  117. * (dd.x * p0 + dd.y * p1 + dd.z * p2 + dd.w * p3);
  118. #endif
  119. }
  120. [vert.hlsl]
  121. void main(float2 a_Vertex : POSITION,
  122. float2 a_TexCoord : TEXCOORD0,
  123. uniform float4x4 u_ZoomSettings,
  124. uniform float4 u_TexelSize,
  125. uniform float4 u_ScreenSize,
  126. out float4 out_Position : POSITION0,
  127. out float4 v_CenterX : TEXCOORD0,
  128. out float4 v_CenterY : TEXCOORD1,
  129. out float4 v_IndexX : TEXCOORD2,
  130. out float4 v_IndexY : TEXCOORD3)
  131. {
  132. out_Position = float4(a_Vertex, 0.0, 1.0);
  133. float4 offsets = float4(0.5, -0.5, 0.015625, -0.015625);
  134. float4 zoomscale = float4(u_ZoomSettings[2][0],
  135. u_ZoomSettings[2][1],
  136. u_ZoomSettings[2][2],
  137. u_ZoomSettings[2][3]);
  138. float4 zoomtx = float4(u_ZoomSettings[0][0],
  139. u_ZoomSettings[0][1],
  140. u_ZoomSettings[0][2],
  141. u_ZoomSettings[0][3]);
  142. float4 zoomty = float4(u_ZoomSettings[1][0],
  143. u_ZoomSettings[1][1],
  144. u_ZoomSettings[1][2],
  145. u_ZoomSettings[1][3]);
  146. v_CenterX = zoomscale * a_TexCoord.x + zoomtx
  147. + offsets.xyxy * u_TexelSize.x;
  148. v_CenterY = zoomscale * a_TexCoord.y - zoomty
  149. + offsets.xyyx * u_TexelSize.y;
  150. v_IndexX = v_CenterX * u_ScreenSize.z - offsets.zwzw;
  151. v_IndexY = v_CenterY * u_ScreenSize.w - offsets.zwwz;
  152. }
  153. [frag.hlsl]
  154. void main(in float4 v_CenterX : TEXCOORD0,
  155. in float4 v_CenterY : TEXCOORD1,
  156. in float4 v_IndexX : TEXCOORD2,
  157. in float4 v_IndexY : TEXCOORD3,
  158. uniform float4 u_TexelSize,
  159. uniform sampler2D u_Texture,
  160. out float4 out_FragColor : COLOR)
  161. {
  162. float4 v05 = float4(0.5, 0.5, 0.5, 0.5);
  163. float4 rx, ry, t0, dx, dy, dd;
  164. rx = u_TexelSize.x + u_TexelSize.z * floor(v_IndexX);
  165. ry = u_TexelSize.y + u_TexelSize.w * floor(v_IndexY);
  166. t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);
  167. dx = rx - v_CenterX;
  168. dy = ry - v_CenterY;
  169. dd = t0 / (0.000001 + (dx * dx) + (dy * dy));
  170. ry = ry * 0.25 + float4(0.0, 0.25, 0.5, 0.75);
  171. float2 t1 = step(dd.xz, dd.yw);
  172. float4 ret = lerp(float4(rx.xz, ry.xz),
  173. float4(rx.yw, ry.yw), t1.xyxy);
  174. dd.xy = lerp(dd.xz, dd.yw, t1);
  175. float t2 = step(dd.x, dd.y);
  176. ret.xy = lerp(ret.xz, ret.yw, t2);
  177. out_FragColor = tex2D(u_Texture, ret.xy);
  178. }