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