|
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 |