Lanczos filter available in GLES.
It uses a default vertex shader, so the existing shader can be dropped.
This commit is contained in:
parent
c6dd3690f5
commit
78c4c7a86e
5 changed files with 81 additions and 50 deletions
|
@ -2,12 +2,14 @@ uniform sampler2D texUnit;
|
|||
uniform vec2 offsets[25];
|
||||
uniform vec4 kernel[25];
|
||||
|
||||
varying vec2 varyingTexCoords;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 sum = texture2D(texUnit, gl_TexCoord[0].st) * kernel[0];
|
||||
vec4 sum = texture2D(texUnit, varyingTexCoords.st) * kernel[0];
|
||||
for (int i = 1; i < 25; i++) {
|
||||
sum += texture2D(texUnit, gl_TexCoord[0].st - offsets[i]) * kernel[i];
|
||||
sum += texture2D(texUnit, gl_TexCoord[0].st + offsets[i]) * kernel[i];
|
||||
sum += texture2D(texUnit, varyingTexCoords.st - offsets[i]) * kernel[i];
|
||||
sum += texture2D(texUnit, varyingTexCoords.st + offsets[i]) * kernel[i];
|
||||
}
|
||||
gl_FragColor = sum;
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
|
|
@ -38,11 +38,9 @@ namespace KWin
|
|||
LanczosFilter::LanczosFilter( QObject* parent )
|
||||
: QObject( parent )
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
, m_offscreenTex( 0 )
|
||||
, m_offscreenTarget( 0 )
|
||||
, m_shader( 0 )
|
||||
#endif
|
||||
#endif
|
||||
, m_inited( false)
|
||||
{
|
||||
|
@ -51,10 +49,8 @@ LanczosFilter::LanczosFilter( QObject* parent )
|
|||
LanczosFilter::~LanczosFilter()
|
||||
{
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
delete m_offscreenTarget;
|
||||
delete m_offscreenTex;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -64,7 +60,6 @@ void LanczosFilter::init()
|
|||
return;
|
||||
m_inited = true;
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig( "kwinrc" );
|
||||
|
||||
|
@ -85,7 +80,6 @@ void LanczosFilter::init()
|
|||
delete m_shader;
|
||||
m_shader = 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -132,7 +126,6 @@ static float lanczos( float x, float a )
|
|||
}
|
||||
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
void LanczosShader::createKernel( float delta, int *size )
|
||||
{
|
||||
const float a = 2.0;
|
||||
|
@ -173,13 +166,11 @@ void LanczosShader::createOffsets( int count, float width, Qt::Orientation direc
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data )
|
||||
{
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
if( effects->compositingType() == KWin::OpenGLCompositing && data.opacity == 1.0 &&
|
||||
if( effects->compositingType() == KWin::OpenGLCompositing &&
|
||||
KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects )
|
||||
{
|
||||
if (!m_inited)
|
||||
|
@ -225,9 +216,23 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region,
|
|||
if( cachedTexture->width() == tw && cachedTexture->height() == th )
|
||||
{
|
||||
cachedTexture->bind();
|
||||
prepareRenderStates( cachedTexture, data.opacity, data.brightness, data.saturation );
|
||||
cachedTexture->render( textureRect, textureRect );
|
||||
restoreRenderStates( cachedTexture, data.opacity, data.brightness, data.saturation );
|
||||
if (ShaderManager::instance()->isValid()) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
|
||||
shader->setUniform("offset", QVector2D(0, 0));
|
||||
shader->setUniform("opacity", (float)data.opacity);
|
||||
shader->setUniform("brightness", (float)data.brightness);
|
||||
shader->setUniform("saturation", (float)data.saturation);
|
||||
shader->setUniform("u_forceAlpha", 0);
|
||||
cachedTexture->render(textureRect, textureRect);
|
||||
ShaderManager::instance()->popShader();
|
||||
glDisable(GL_BLEND);
|
||||
} else {
|
||||
prepareRenderStates( cachedTexture, data.opacity, data.brightness, data.saturation );
|
||||
cachedTexture->render( textureRect, textureRect );
|
||||
restoreRenderStates( cachedTexture, data.opacity, data.brightness, data.saturation );
|
||||
}
|
||||
cachedTexture->unbind();
|
||||
m_timer.start( 5000, this );
|
||||
return;
|
||||
|
@ -254,6 +259,7 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region,
|
|||
updateOffscreenSurfaces();
|
||||
effects->pushRenderTarget( m_offscreenTarget );
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
w->sceneWindow()->performPaint( mask, infiniteRegion(), thumbData );
|
||||
|
||||
|
@ -276,13 +282,21 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region,
|
|||
|
||||
// Draw the window back into the FBO, this time scaled horizontally
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
QVector<float> verts;
|
||||
QVector<float> texCoords;
|
||||
verts.reserve(12);
|
||||
texCoords.reserve(12);
|
||||
|
||||
glBegin( GL_QUADS );
|
||||
glTexCoord2f( 0, 0 ); glVertex2i( 0, 0 ); // Top left
|
||||
glTexCoord2f( 1, 0 ); glVertex2i( tw, 0 ); // Top right
|
||||
glTexCoord2f( 1, 1 ); glVertex2i( tw, sh ); // Bottom right
|
||||
glTexCoord2f( 0, 1 ); glVertex2i( 0, sh ); // Bottom left
|
||||
glEnd();
|
||||
texCoords << 1.0 << 0.0; verts << tw << 0.0; // Top right
|
||||
texCoords << 0.0 << 0.0; verts << 0.0 << 0.0; // Top left
|
||||
texCoords << 0.0 << 1.0; verts << 0.0 << sh; // Bottom left
|
||||
texCoords << 0.0 << 1.0; verts << 0.0 << sh; // Bottom left
|
||||
texCoords << 1.0 << 1.0; verts << tw << sh; // Bottom right
|
||||
texCoords << 1.0 << 0.0; verts << tw << 0.0; // Top right
|
||||
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
|
||||
vbo->reset();
|
||||
vbo->setData(6, 2, verts.constData(), texCoords.constData());
|
||||
vbo->render(GL_TRIANGLES);
|
||||
|
||||
// At this point we don't need the scratch texture anymore
|
||||
tex.unbind();
|
||||
|
@ -306,12 +320,16 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region,
|
|||
// coordinates on the screen, while scaling it vertically and blending it.
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
glBegin( GL_QUADS );
|
||||
glTexCoord2f( 0, 0 ); glVertex2i( 0, 0 ); // Top left
|
||||
glTexCoord2f( 1, 0 ); glVertex2i( tw, 0 ); // Top right
|
||||
glTexCoord2f( 1, 1 ); glVertex2i( tw, th ); // Bottom right
|
||||
glTexCoord2f( 0, 1 ); glVertex2i( 0, th ); // Bottom left
|
||||
glEnd();
|
||||
verts.clear();
|
||||
|
||||
verts << tw << 0.0; // Top right
|
||||
verts << 0.0 << 0.0; // Top left
|
||||
verts << 0.0 << th; // Bottom left
|
||||
verts << 0.0 << th; // Bottom left
|
||||
verts << tw << th; // Bottom right
|
||||
verts << tw << 0.0; // Top right
|
||||
vbo->setData(6, 2, verts.constData(), texCoords.constData());
|
||||
vbo->render(GL_TRIANGLES);
|
||||
|
||||
tex2.unbind();
|
||||
tex2.discard();
|
||||
|
@ -325,9 +343,23 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region,
|
|||
cache->bind();
|
||||
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - th, tw, th );
|
||||
effects->popRenderTarget();
|
||||
prepareRenderStates( cache, data.opacity, data.brightness, data.saturation );
|
||||
cache->render( textureRect, textureRect );
|
||||
restoreRenderStates( cache, data.opacity, data.brightness, data.saturation );
|
||||
if (ShaderManager::instance()->isValid()) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
|
||||
shader->setUniform("offset", QVector2D(0, 0));
|
||||
shader->setUniform("opacity", (float)data.opacity);
|
||||
shader->setUniform("brightness", (float)data.brightness);
|
||||
shader->setUniform("saturation", (float)data.saturation);
|
||||
shader->setUniform("u_forceAlpha", 0);
|
||||
cache->render(textureRect, textureRect);
|
||||
ShaderManager::instance()->popShader();
|
||||
glDisable(GL_BLEND);
|
||||
} else {
|
||||
prepareRenderStates( cache, data.opacity, data.brightness, data.saturation );
|
||||
cache->render( textureRect, textureRect );
|
||||
restoreRenderStates( cache, data.opacity, data.brightness, data.saturation );
|
||||
}
|
||||
cache->unbind();
|
||||
w->setData( LanczosCacheRole, QVariant::fromValue( static_cast<void*>( cache )));
|
||||
|
||||
|
@ -336,7 +368,6 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region,
|
|||
return;
|
||||
}
|
||||
} // if ( effects->compositingType() == KWin::OpenGLCompositing )
|
||||
#endif
|
||||
#endif
|
||||
w->sceneWindow()->performPaint( mask, region, data );
|
||||
} // End of function
|
||||
|
@ -520,7 +551,6 @@ void LanczosFilter::restoreRenderStates( GLTexture* tex, double opacity, double
|
|||
* LanczosShader
|
||||
************************************************/
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
LanczosShader::LanczosShader( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_shader( 0 )
|
||||
|
@ -531,28 +561,33 @@ LanczosShader::LanczosShader( QObject* parent )
|
|||
LanczosShader::~LanczosShader()
|
||||
{
|
||||
delete m_shader;
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
if( m_arbProgram )
|
||||
{
|
||||
glDeleteProgramsARB(1, &m_arbProgram);
|
||||
m_arbProgram = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LanczosShader::bind()
|
||||
{
|
||||
if( m_shader )
|
||||
m_shader->bind();
|
||||
ShaderManager::instance()->pushShader(m_shader);
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
{
|
||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_arbProgram);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LanczosShader::unbind()
|
||||
{
|
||||
if( m_shader )
|
||||
m_shader->unbind();
|
||||
ShaderManager::instance()->popShader();
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
{
|
||||
int boundObject;
|
||||
|
@ -563,6 +598,7 @@ void LanczosShader::unbind()
|
|||
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LanczosShader::setUniforms()
|
||||
|
@ -573,6 +609,7 @@ void LanczosShader::setUniforms()
|
|||
glUniform2fv( m_uOffsets, 25, (const GLfloat*)m_offsets );
|
||||
glUniform4fv( m_uKernel, 25, (const GLfloat*)m_kernel );
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
else
|
||||
{
|
||||
for( int i=0; i<25; ++i )
|
||||
|
@ -584,6 +621,7 @@ void LanczosShader::setUniforms()
|
|||
glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, i+25, m_kernel[i].x(), m_kernel[i].y(), m_kernel[i].z(), m_kernel[i].w() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool LanczosShader::init()
|
||||
|
@ -592,7 +630,7 @@ bool LanczosShader::init()
|
|||
GLShader::vertexShaderSupported() &&
|
||||
GLRenderTarget::supported() )
|
||||
{
|
||||
m_shader = new GLShader(":/resources/lanczos-vertex.glsl", ":/resources/lanczos-fragment.glsl");
|
||||
m_shader = ShaderManager::instance()->loadFragmentShader(ShaderManager::SimpleShader, ":/resources/lanczos-fragment.glsl");
|
||||
if (m_shader->isValid())
|
||||
{
|
||||
m_shader->bind();
|
||||
|
@ -610,6 +648,10 @@ bool LanczosShader::init()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
// no ARB shader in GLES
|
||||
return false;
|
||||
#else
|
||||
// try to create an ARB Shader
|
||||
if( !hasGLExtension("GL_ARB_fragment_program") )
|
||||
return false;
|
||||
|
@ -652,8 +694,8 @@ bool LanczosShader::init()
|
|||
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
kDebug( 1212 ) << "ARB Shader compiled, id: " << m_arbProgram;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -39,10 +39,8 @@ class GLTexture;
|
|||
class GLRenderTarget;
|
||||
class GLShader;
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
class LanczosShader;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class LanczosFilter
|
||||
: public QObject
|
||||
|
@ -64,16 +62,13 @@ class LanczosFilter
|
|||
GLTexture *m_offscreenTex;
|
||||
GLRenderTarget *m_offscreenTarget;
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
LanczosShader *m_shader;
|
||||
#endif
|
||||
#endif
|
||||
QBasicTimer m_timer;
|
||||
bool m_inited;
|
||||
};
|
||||
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
class LanczosShader
|
||||
: public QObject
|
||||
{
|
||||
|
@ -100,7 +95,6 @@ class LanczosShader
|
|||
uint m_arbProgram; // TODO: GLuint
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/resources">
|
||||
<file>lanczos-vertex.glsl</file>
|
||||
<file>lanczos-fragment.glsl</file>
|
||||
<file>scene-vertex.glsl</file>
|
||||
<file>scene-fragment.glsl</file>
|
||||
|
|
Loading…
Reference in a new issue