Lines 21-26
Link Here
|
21 |
#include "system.h" |
21 |
#include "system.h" |
22 |
#include "VideoFilterShader.h" |
22 |
#include "VideoFilterShader.h" |
23 |
#include "utils/log.h" |
23 |
#include "utils/log.h" |
|
|
24 |
#include "ConvolutionKernels.h" |
24 |
|
25 |
|
25 |
#include <string> |
26 |
#include <string> |
26 |
#include <math.h> |
27 |
#include <math.h> |
Lines 63-122
Link Here
|
63 |
|
64 |
|
64 |
BicubicFilterShader::BicubicFilterShader(float B, float C) |
65 |
BicubicFilterShader::BicubicFilterShader(float B, float C) |
65 |
{ |
66 |
{ |
66 |
string shaderf = |
67 |
PixelShader()->LoadSource("bicubic.glsl"); |
67 |
"uniform sampler2D img;" |
|
|
68 |
"uniform float stepx;" |
69 |
"uniform float stepy;" |
70 |
"uniform sampler2D kernelTex;" |
71 |
|
72 |
"vec4 cubicFilter(float xValue, vec4 c0, vec4 c1, vec4 c2, vec4 c3)" |
73 |
"{" |
74 |
" vec4 h = texture2D(kernelTex, vec2(xValue, 0.5));" |
75 |
" vec4 r = c0 * h.r;" |
76 |
" r += c1 * h.g;" |
77 |
" r += c2 * h.b;" |
78 |
" r += c3 * h.a;" |
79 |
" return r;" |
80 |
"}" |
81 |
"" |
82 |
"void main()" |
83 |
"{" |
84 |
"vec2 f = vec2(gl_TexCoord[0].x / stepx , gl_TexCoord[0].y / stepy);" |
85 |
"f = fract(f);" |
86 |
"vec4 t0 = cubicFilter(f.x," |
87 |
"texture2D(img, gl_TexCoord[0].xy + vec2(-stepx, -stepy))," |
88 |
"texture2D(img, gl_TexCoord[0].xy + vec2(0.0, -stepy))," |
89 |
"texture2D(img, gl_TexCoord[0].xy + vec2(stepx, -stepy))," |
90 |
"texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, -stepy)));" |
91 |
"" |
92 |
"vec4 t1 = cubicFilter(f.x," |
93 |
"texture2D(img, gl_TexCoord[0].xy + vec2(-stepx, 0.0))," |
94 |
"texture2D(img, gl_TexCoord[0].xy + vec2(0.0, 0.0))," |
95 |
"texture2D(img, gl_TexCoord[0].xy + vec2(stepx, 0.0))," |
96 |
"texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, 0.0)));" |
97 |
"" |
98 |
"vec4 t2 = cubicFilter(f.x," |
99 |
"texture2D(img, gl_TexCoord[0].xy + vec2(-stepx, stepy))," |
100 |
"texture2D(img, gl_TexCoord[0].xy + vec2(0.0, stepy))," |
101 |
"texture2D(img, gl_TexCoord[0].xy + vec2(stepx, stepy))," |
102 |
"texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, stepy)));" |
103 |
"" |
104 |
"vec4 t3 = cubicFilter(f.x," |
105 |
"texture2D(img, gl_TexCoord[0].xy + vec2(-stepx, 2.0*stepy))," |
106 |
"texture2D(img, gl_TexCoord[0].xy + vec2(0, 2.0*stepy))," |
107 |
"texture2D(img, gl_TexCoord[0].xy + vec2(stepx, 2.0*stepy))," |
108 |
"texture2D(img, gl_TexCoord[0].xy + vec2(2.0*stepx, 2.0*stepy)));" |
109 |
|
110 |
"gl_FragColor = cubicFilter(f.y, t0, t1, t2, t3) ;" |
111 |
"gl_FragColor.a = gl_Color.a;" |
112 |
"}"; |
113 |
PixelShader()->SetSource(shaderf); |
114 |
m_kernelTex1 = 0; |
68 |
m_kernelTex1 = 0; |
115 |
m_B = B; |
69 |
m_B = B; |
116 |
m_C = C; |
70 |
m_C = C; |
117 |
if (B<=0) |
71 |
if (B<0) |
118 |
m_B=1.0f/3.0f; |
72 |
m_B=1.0f/3.0f; |
119 |
if (C<=0) |
73 |
if (C<0) |
120 |
m_C=1.0f/3.0f; |
74 |
m_C=1.0f/3.0f; |
121 |
} |
75 |
} |
122 |
|
76 |
|
Lines 209-216
Link Here
|
209 |
glBindTexture(GL_TEXTURE_2D, m_kernelTex1); |
163 |
glBindTexture(GL_TEXTURE_2D, m_kernelTex1); |
210 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
164 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
211 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
165 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
212 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
166 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); |
213 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
167 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); |
214 |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, size, 1, 0, GL_RGBA, GL_FLOAT, img); |
168 |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, size, 1, 0, GL_RGBA, GL_FLOAT, img); |
215 |
|
169 |
|
216 |
glActiveTexture(GL_TEXTURE0); |
170 |
glActiveTexture(GL_TEXTURE0); |
Lines 254-257
Link Here
|
254 |
return val; |
208 |
return val; |
255 |
} |
209 |
} |
256 |
|
210 |
|
|
|
211 |
ConvolutionFilterShader::ConvolutionFilterShader(ESCALINGMETHOD method) |
212 |
{ |
213 |
m_method = method; |
214 |
m_kernelTex1 = 0; |
215 |
|
216 |
string shadername; |
217 |
string defines; |
218 |
|
219 |
if (m_method == VS_SCALINGMETHOD_CUBIC || |
220 |
m_method == VS_SCALINGMETHOD_LANCZOS2 || |
221 |
m_method == VS_SCALINGMETHOD_LANCZOS3_FAST) |
222 |
shadername = "convolution-4x4.glsl"; |
223 |
else if (m_method == VS_SCALINGMETHOD_LANCZOS3) |
224 |
shadername = "convolution-6x6.glsl"; |
225 |
|
226 |
m_floattex = glewIsSupported("GL_ARB_texture_float"); |
227 |
|
228 |
if (m_floattex) |
229 |
defines = "#define HAS_FLOAT_TEXTURE 1\n"; |
230 |
else |
231 |
defines = "#define HAS_FLOAT_TEXTURE 0\n"; |
232 |
|
233 |
CLog::Log(LOGDEBUG, "GL: ConvolutionFilterShader: using %s defines: %s", shadername.c_str(), defines.c_str()); |
234 |
PixelShader()->LoadSource(shadername, defines); |
235 |
} |
236 |
|
237 |
void ConvolutionFilterShader::OnCompiledAndLinked() |
238 |
{ |
239 |
// obtain shader attribute handles on successfull compilation |
240 |
m_hSourceTex = glGetUniformLocation(ProgramHandle(), "img"); |
241 |
m_hStepX = glGetUniformLocation(ProgramHandle(), "stepx"); |
242 |
m_hStepY = glGetUniformLocation(ProgramHandle(), "stepy"); |
243 |
m_hKernTex = glGetUniformLocation(ProgramHandle(), "kernelTex"); |
244 |
|
245 |
CConvolutionKernel kernel(m_method, 256); |
246 |
|
247 |
if (m_kernelTex1) |
248 |
{ |
249 |
glDeleteTextures(1, &m_kernelTex1); |
250 |
m_kernelTex1 = 0; |
251 |
} |
252 |
|
253 |
glGenTextures(1, &m_kernelTex1); |
254 |
|
255 |
if ((m_kernelTex1<=0)) |
256 |
{ |
257 |
CLog::Log(LOGERROR, "GL: ConvolutionFilterShader: Error creating kernel texture"); |
258 |
return; |
259 |
} |
260 |
|
261 |
glActiveTexture(GL_TEXTURE2); |
262 |
|
263 |
//if float textures are supported, we can load the kernel as a 1d float texture |
264 |
//if not, we load it as a 2d texture with 2 rows, where row 0 contains the high byte |
265 |
//and row 1 contains the low byte, which can be converted in the shader |
266 |
if (m_floattex) |
267 |
{ |
268 |
glBindTexture(GL_TEXTURE_1D, m_kernelTex1); |
269 |
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
270 |
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
271 |
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
272 |
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
273 |
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16F_ARB, kernel.GetSize(), 0, GL_RGBA, GL_FLOAT, kernel.GetFloatPixels()); |
274 |
} |
275 |
else |
276 |
{ |
277 |
glBindTexture(GL_TEXTURE_2D, m_kernelTex1); |
278 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
279 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
280 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
281 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
282 |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kernel.GetSize(), 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kernel.GetIntFractPixels()); |
283 |
} |
284 |
|
285 |
glActiveTexture(GL_TEXTURE0); |
286 |
|
287 |
VerifyGLState(); |
288 |
} |
289 |
|
290 |
bool ConvolutionFilterShader::OnEnabled() |
291 |
{ |
292 |
// set shader attributes once enabled |
293 |
glActiveTexture(GL_TEXTURE2); |
294 |
|
295 |
if (m_floattex) |
296 |
glBindTexture(GL_TEXTURE_1D, m_kernelTex1); |
297 |
else |
298 |
glBindTexture(GL_TEXTURE_2D, m_kernelTex1); |
299 |
|
300 |
glActiveTexture(GL_TEXTURE0); |
301 |
glUniform1i(m_hSourceTex, m_sourceTexUnit); |
302 |
glUniform1i(m_hKernTex, 2); |
303 |
glUniform1f(m_hStepX, m_stepX); |
304 |
glUniform1f(m_hStepY, m_stepY); |
305 |
VerifyGLState(); |
306 |
return true; |
307 |
} |
308 |
|
309 |
void ConvolutionFilterShader::Free() |
310 |
{ |
311 |
if (m_kernelTex1) |
312 |
glDeleteTextures(1, &m_kernelTex1); |
313 |
m_kernelTex1 = 0; |
314 |
BaseVideoFilterShader::Free(); |
315 |
} |
316 |
|
257 |
#endif |
317 |
#endif |