您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

130 行
4.6 KiB

  1. [vert.glsl]
  2. #version 130
  3. uniform mat4 u_zoom_settings;
  4. uniform vec4 u_texel_size;
  5. uniform vec4 u_screen_size;
  6. attribute vec2 in_TexCoord;
  7. attribute vec2 in_Position;
  8. out vec4 v_center_x, v_center_y, v_index_x, v_index_y;
  9. void main(void)
  10. {
  11. gl_Position = vec4(in_Position, 0.0, 1.0);
  12. /* Center point in [-.5,.5], apply zoom and translation
  13. * transformation, and go back to texture coordinates
  14. * in [0,1]. That's the ideal point we would like to
  15. * compute the value for. Then add or remove half the
  16. * size of a texel: the distance from this new point to
  17. * the final point will be our error. */
  18. vec4 offsets = vec4(0.5, -0.5, 0.015625, -0.015625);
  19. vec4 zoomscale = vec4(u_zoom_settings[0][2],
  20. u_zoom_settings[1][2],
  21. u_zoom_settings[2][2],
  22. u_zoom_settings[3][2]);
  23. vec4 zoomtx = vec4(u_zoom_settings[0][0],
  24. u_zoom_settings[1][0],
  25. u_zoom_settings[2][0],
  26. u_zoom_settings[3][0]);
  27. vec4 zoomty = vec4(u_zoom_settings[0][1],
  28. u_zoom_settings[1][1],
  29. u_zoom_settings[2][1],
  30. u_zoom_settings[3][1]);
  31. v_center_x = zoomscale * in_TexCoord.x + zoomtx
  32. + offsets.xyxy * u_texel_size.x;
  33. v_center_y = zoomscale * in_TexCoord.y - zoomty
  34. + offsets.xyyx * u_texel_size.y;
  35. /* Precompute the multiple of one texel where our ideal
  36. * point lies. The fragment shader will call floor() on
  37. * this value. We add or remove a slight offset to avoid
  38. * rounding issues at the image's edges. */
  39. v_index_x = v_center_x * u_screen_size.z - offsets.zwzw;
  40. v_index_y = v_center_y * u_screen_size.w - offsets.zwwz;
  41. }
  42. [frag.glsl]
  43. #version 130
  44. #if defined GL_ES
  45. precision highp float;
  46. #endif
  47. uniform vec4 u_texel_size;
  48. uniform sampler2D u_texture;
  49. in vec4 v_center_x, v_center_y, v_index_x, v_index_y;
  50. void main(void)
  51. {
  52. vec4 v05 = vec4(0.5, 0.5, 0.5, 0.5);
  53. vec4 rx, ry, t0, dx, dy, dd;
  54. /* Get a pixel coordinate from each slice into rx & ry */
  55. rx = u_texel_size.x + u_texel_size.z * floor(v_index_x);
  56. ry = u_texel_size.y + u_texel_size.w * floor(v_index_y);
  57. /* Compute inverse distance to expected pixel in dd,
  58. * and put zero if we fall outside the texture. */
  59. t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);
  60. dx = rx - v_center_x;
  61. dy = ry - v_center_y;
  62. #if 0
  63. vec4 dd = t0 * (abs(dx) + abs(dy));
  64. vec4 dd = t0 / (0.001 + sqrt((dx * dx) + (dy * dy)));
  65. #endif
  66. dd = t0 / (0.000001 + (dx * dx) + (dy * dy));
  67. /* Modify Y coordinate to select proper quarter. */
  68. ry = ry * 0.25 + vec4(0.0, 0.25, 0.5, 0.75);
  69. #if 1
  70. # if 0
  71. /* XXX: disabled until we can autodetect i915 */
  72. /* t1.x <-- dd.x > dd.y */
  73. /* t1.y <-- dd.z > dd.w */
  74. vec2 t1 = step(dd.xz, dd.yw);
  75. /* ret.x <-- max(rx.x, rx.y) wrt. t1.x */
  76. /* ret.y <-- max(rx.z, rx.w) wrt. t1.y */
  77. /* ret.z <-- max(ry.x, ry.y) wrt. t1.x */
  78. /* ret.w <-- max(ry.z, ry.w) wrt. t1.y */
  79. vec4 ret = mix(vec4(rx.xz, ry.xz),
  80. vec4(rx.yw, ry.yw), t1.xyxy);
  81. /* dd.x <-- max(dd.x, dd.y) */
  82. /* dd.z <-- max(dd.z, dd.w) */
  83. dd.xy = mix(dd.xz, dd.yw, t1);
  84. /* t2 <-- dd.x > dd.z */
  85. float t2 = step(dd.x, dd.y);
  86. /* ret.x <-- max(ret.x, ret.y); */
  87. /* ret.y <-- max(ret.z, ret.w); */
  88. ret.xy = mix(ret.xz, ret.yw, t2);
  89. # else
  90. /* Fallback for i915 cards -- the trick to reduce the
  91. * number of operations is to compute both step(a,b)
  92. * and step(b,a) and hope that their sum is 1. This is
  93. * almost always the case, and when it isn't we can
  94. * afford to have a few wrong pixels. However, a real
  95. * problem is when panning the image, because half the
  96. * screen is likely to flicker. To avoid this problem,
  97. * we cheat a little (see m_translate comment above). */
  98. vec4 t1 = step(dd.xzyw, dd.ywxz);
  99. vec4 ret = vec4(rx.xz, ry.xz) * t1.zwzw
  100. + vec4(rx.yw, ry.yw) * t1.xyxy;
  101. dd.xy = dd.xz * t1.zw + dd.yw * t1.xy;
  102. vec2 t2 = step(dd.xy, dd.yx);
  103. ret.xy = ret.xz * t2.yy + ret.yw * t2.xx;
  104. # endif
  105. /* Nearest neighbour */
  106. gl_FragColor = texture2D(u_texture, ret.xy);
  107. #else
  108. /* Alternate version: some kind of linear interpolation */
  109. vec4 p0 = texture2D(u_texture, vec2(rx.x, ry.x));
  110. vec4 p1 = texture2D(u_texture, vec2(rx.y, ry.y));
  111. vec4 p2 = texture2D(u_texture, vec2(rx.z, ry.z));
  112. vec4 p3 = texture2D(u_texture, vec2(rx.w, ry.w));
  113. gl_FragColor = 1.0 / (dd.x + dd.y + dd.z + dd.w)
  114. * (dd.x * p0 + dd.y * p1 + dd.z * p2 + dd.w * p3);
  115. #endif
  116. }