LookingGlass ported to GLES.
LookingGlass does not inherit ShaderEffect any more and uses just a fragment shader. It still renders to a FBO, this could probably be improved.
This commit is contained in:
parent
75e926a6d7
commit
863726a085
7 changed files with 158 additions and 59 deletions
|
@ -93,6 +93,7 @@ if( KWIN_HAVE_OPENGL_COMPOSITING )
|
|||
include( cube/CMakeLists.txt )
|
||||
include( flipswitch/CMakeLists.txt )
|
||||
include( glide/CMakeLists.txt )
|
||||
include( lookingglass/CMakeLists.txt )
|
||||
include( magnifier/CMakeLists.txt )
|
||||
include( mousemark/CMakeLists.txt )
|
||||
include( screenshot/CMakeLists.txt )
|
||||
|
@ -106,7 +107,6 @@ if( KWIN_HAVE_OPENGL_COMPOSITING AND NOT KWIN_HAVE_OPENGLES_COMPOSITING )
|
|||
include( blur/CMakeLists.txt )
|
||||
include( explosion/CMakeLists.txt )
|
||||
include( invert/CMakeLists.txt )
|
||||
include( lookingglass/CMakeLists.txt )
|
||||
include( sharpen/CMakeLists.txt )
|
||||
include( snow/CMakeLists.txt )
|
||||
endif( KWIN_HAVE_OPENGL_COMPOSITING AND NOT KWIN_HAVE_OPENGLES_COMPOSITING )
|
||||
|
|
|
@ -44,6 +44,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "cube/cubeslide_config.h"
|
||||
#include "flipswitch/flipswitch_config.h"
|
||||
#include "glide/glide_config.h"
|
||||
#include "lookingglass/lookingglass_config.h"
|
||||
#include "magnifier/magnifier_config.h"
|
||||
#include "mousemark/mousemark_config.h"
|
||||
#include "trackmouse/trackmouse_config.h"
|
||||
|
@ -51,7 +52,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#ifndef KWIN_HAVE_OPENGLES
|
||||
#include "blur/blur_config.h"
|
||||
#include "invert/invert_config.h"
|
||||
#include "lookingglass/lookingglass_config.h"
|
||||
#include "sharpen/sharpen_config.h"
|
||||
#include "snow/snow_config.h"
|
||||
#endif
|
||||
|
@ -86,6 +86,7 @@ KWIN_EFFECT_CONFIG_MULTIPLE( builtins,
|
|||
KWIN_EFFECT_CONFIG_SINGLE( cubeslide, CubeSlideEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( flipswitch, FlipSwitchEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( glide, GlideEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( lookingglass, LookingGlassEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( magnifier, MagnifierEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( mousemark, MouseMarkEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( trackmouse, TrackMouseEffectConfig )
|
||||
|
@ -93,7 +94,6 @@ KWIN_EFFECT_CONFIG_MULTIPLE( builtins,
|
|||
#ifndef KWIN_HAVE_OPENGLES
|
||||
KWIN_EFFECT_CONFIG_SINGLE( blur, BlurEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( invert, InvertEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( lookingglass, LookingGlassEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( sharpen, SharpenEffectConfig )
|
||||
KWIN_EFFECT_CONFIG_SINGLE( snow, SnowEffectConfig )
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,6 @@ install( FILES
|
|||
# Data files
|
||||
install( FILES
|
||||
lookingglass/data/lookingglass.frag
|
||||
lookingglass/data/lookingglass.vert
|
||||
DESTINATION ${DATA_INSTALL_DIR}/kwin )
|
||||
|
||||
#######################################
|
||||
|
|
|
@ -1,33 +1,25 @@
|
|||
uniform sampler2D sceneTex;
|
||||
uniform float textureWidth;
|
||||
uniform float textureHeight;
|
||||
uniform float cursorX;
|
||||
uniform float cursorY;
|
||||
uniform float zoom;
|
||||
uniform float radius;
|
||||
uniform sampler2D sample;
|
||||
uniform vec2 u_cursor;
|
||||
uniform float u_zoom;
|
||||
uniform float u_radius;
|
||||
uniform vec2 u_textureSize;
|
||||
|
||||
varying vec2 varyingTexCoords;
|
||||
|
||||
#define PI 3.14159
|
||||
|
||||
// Converts pixel coordinates to texture coordinates
|
||||
vec2 pix2tex(vec2 pix)
|
||||
{
|
||||
return vec2(pix.x / textureWidth, 1.0 - pix.y / textureHeight);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texcoord = gl_TexCoord[0].xy;
|
||||
|
||||
float dx = cursorX - texcoord.x;
|
||||
float dy = cursorY - texcoord.y;
|
||||
float dist = sqrt(dx*dx + dy*dy);
|
||||
if(dist < radius)
|
||||
{
|
||||
float disp = sin(dist / radius * PI) * (zoom - 1.0) * 20.0;
|
||||
texcoord.x += dx / dist * disp;
|
||||
texcoord.y += dy / dist * disp;
|
||||
vec2 d = u_cursor - varyingTexCoords;
|
||||
float dist = sqrt(d.x*d.x + d.y*d.y);
|
||||
vec2 texcoord = varyingTexCoords;
|
||||
if (dist < u_radius) {
|
||||
float disp = sin(dist / u_radius * PI) * (u_zoom - 1.0) * 20.0;
|
||||
texcoord += d / dist * disp;
|
||||
}
|
||||
|
||||
gl_FragColor = texture2D(sceneTex, pix2tex(texcoord));
|
||||
texcoord = texcoord/u_textureSize;
|
||||
texcoord.t = 1.0 - texcoord.t;
|
||||
gl_FragColor = texture2D(sample, texcoord);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
void main()
|
||||
{
|
||||
gl_TexCoord[0].xy = gl_Vertex.xy;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
|
@ -28,6 +28,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <kconfiggroup.h>
|
||||
#include <klocale.h>
|
||||
#include <kdebug.h>
|
||||
#include <KDE/KGlobal>
|
||||
#include <KDE/KStandardDirs>
|
||||
#include <QVector2D>
|
||||
|
||||
#include <kmessagebox.h>
|
||||
|
||||
|
@ -35,15 +38,21 @@ namespace KWin
|
|||
{
|
||||
|
||||
KWIN_EFFECT( lookingglass, LookingGlassEffect )
|
||||
KWIN_EFFECT_SUPPORTED( lookingglass, ShaderEffect::supported() )
|
||||
KWIN_EFFECT_SUPPORTED( lookingglass, LookingGlassEffect::supported() )
|
||||
|
||||
|
||||
LookingGlassEffect::LookingGlassEffect() : QObject(), ShaderEffect("lookingglass")
|
||||
LookingGlassEffect::LookingGlassEffect()
|
||||
: QObject()
|
||||
, zoom( 1.0f )
|
||||
, target_zoom( 1.0f )
|
||||
, polling( false )
|
||||
, m_texture( NULL )
|
||||
, m_fbo( NULL )
|
||||
, m_vbo( NULL )
|
||||
, m_shader( NULL )
|
||||
, m_enabled( false )
|
||||
, m_valid( false )
|
||||
{
|
||||
zoom = 1.0f;
|
||||
target_zoom = 1.0f;
|
||||
polling = false;
|
||||
|
||||
actionCollection = new KActionCollection( this );
|
||||
actionCollection->setConfigGlobal(true);
|
||||
actionCollection->setConfigGroup("LookingGlass");
|
||||
|
@ -60,8 +69,19 @@ LookingGlassEffect::LookingGlassEffect() : QObject(), ShaderEffect("lookingglass
|
|||
|
||||
LookingGlassEffect::~LookingGlassEffect()
|
||||
{
|
||||
delete m_texture;
|
||||
delete m_fbo;
|
||||
delete m_shader;
|
||||
delete m_vbo;
|
||||
}
|
||||
|
||||
bool LookingGlassEffect::supported()
|
||||
{
|
||||
return GLRenderTarget::supported() &&
|
||||
GLShader::fragmentShaderSupported() &&
|
||||
(effects->compositingType() == OpenGLCompositing);
|
||||
}
|
||||
|
||||
void LookingGlassEffect::reconfigure( ReconfigureFlags )
|
||||
{
|
||||
KConfigGroup conf = EffectsHandler::effectConfig("LookingGlass");
|
||||
|
@ -69,8 +89,61 @@ void LookingGlassEffect::reconfigure( ReconfigureFlags )
|
|||
radius = initialradius;
|
||||
kDebug(1212) << QString("Radius from config: %1").arg(radius) << endl;
|
||||
actionCollection->readSettings();
|
||||
m_valid = loadData();
|
||||
}
|
||||
|
||||
bool LookingGlassEffect::loadData()
|
||||
{
|
||||
// If NPOT textures are not supported, use nearest power-of-two sized
|
||||
// texture. It wastes memory, but it's possible to support systems without
|
||||
// NPOT textures that way
|
||||
int texw = displayWidth();
|
||||
int texh = displayHeight();
|
||||
if (!GLTexture::NPOTTextureSupported()) {
|
||||
kWarning( 1212 ) << "NPOT textures not supported, wasting some memory" ;
|
||||
texw = nearestPowerOfTwo(texw);
|
||||
texh = nearestPowerOfTwo(texh);
|
||||
}
|
||||
// Create texture and render target
|
||||
m_texture = new GLTexture(texw, texh);
|
||||
m_texture->setFilter(GL_LINEAR_MIPMAP_LINEAR);
|
||||
m_texture->setWrapMode(GL_CLAMP_TO_EDGE);
|
||||
|
||||
m_fbo = new GLRenderTarget(m_texture);
|
||||
if (!m_fbo->valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString fragmentshader = KGlobal::dirs()->findResource("data", "kwin/lookingglass.frag");
|
||||
m_shader = ShaderManager::instance()->loadFragmentShader(ShaderManager::SimpleShader, fragmentshader);
|
||||
if (m_shader->isValid()) {
|
||||
ShaderManager::instance()->pushShader(m_shader);
|
||||
m_shader->setUniform("u_textureSize", QVector2D(displayWidth(), displayHeight()));
|
||||
ShaderManager::instance()->popShader();
|
||||
} else {
|
||||
kError(1212) << "The shader failed to load!" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_vbo = new GLVertexBuffer(GLVertexBuffer::Static);
|
||||
QVector<float> verts;
|
||||
QVector<float> texcoords;
|
||||
texcoords << displayWidth() << 0.0;
|
||||
verts << displayWidth() << 0.0;
|
||||
texcoords << 0.0 << 0.0;
|
||||
verts << 0.0 << 0.0;
|
||||
texcoords << 0.0 << displayHeight();
|
||||
verts << 0.0 << displayHeight();
|
||||
texcoords << 0.0 << displayHeight();
|
||||
verts << 0.0 << displayHeight();
|
||||
texcoords << displayWidth() << displayHeight();
|
||||
verts << displayWidth() << displayHeight();
|
||||
texcoords << displayWidth() << 0.0;
|
||||
verts << displayWidth() << 0.0;
|
||||
m_vbo->setData(6, 2, verts.constData(), texcoords.constData());
|
||||
return true;
|
||||
}
|
||||
|
||||
void LookingGlassEffect::toggle()
|
||||
{
|
||||
if( target_zoom == 1.0f )
|
||||
|
@ -81,7 +154,7 @@ void LookingGlassEffect::toggle()
|
|||
polling = true;
|
||||
effects->startMousePolling();
|
||||
}
|
||||
setEnabled( true );
|
||||
m_enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -91,14 +164,14 @@ void LookingGlassEffect::toggle()
|
|||
polling = false;
|
||||
effects->stopMousePolling();
|
||||
}
|
||||
setEnabled( false );
|
||||
m_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void LookingGlassEffect::zoomIn()
|
||||
{
|
||||
target_zoom = qMin(7.0, target_zoom + 0.5);
|
||||
setEnabled( true );
|
||||
m_enabled = true;
|
||||
if( !polling )
|
||||
{
|
||||
polling = true;
|
||||
|
@ -113,7 +186,7 @@ void LookingGlassEffect::zoomOut()
|
|||
if( target_zoom < 1 )
|
||||
{
|
||||
target_zoom = 1;
|
||||
setEnabled( false );
|
||||
m_enabled = false;
|
||||
if( polling )
|
||||
{
|
||||
polling = false;
|
||||
|
@ -135,34 +208,60 @@ void LookingGlassEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
|||
kDebug(1212) << "zoom is now " << zoom;
|
||||
radius = qBound((double)initialradius, initialradius * zoom, 3.5*initialradius);
|
||||
|
||||
if( zoom > 1.0f )
|
||||
{
|
||||
shader()->bind();
|
||||
shader()->setUniform("zoom", (float)zoom);
|
||||
shader()->setUniform("radius", (float)radius);
|
||||
shader()->unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
setEnabled( false );
|
||||
}
|
||||
if( zoom <= 1.0f ) {
|
||||
m_enabled = false;
|
||||
}
|
||||
|
||||
effects->addRepaint( cursorPos().x() - radius, cursorPos().y() - radius, 2*radius, 2*radius );
|
||||
}
|
||||
if (m_valid && m_enabled) {
|
||||
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
|
||||
// Start rendering to texture
|
||||
effects->pushRenderTarget(m_fbo);
|
||||
checkGLError("push Render Target");
|
||||
}
|
||||
|
||||
ShaderEffect::prePaintScreen( data, time );
|
||||
effects->prePaintScreen( data, time );
|
||||
}
|
||||
|
||||
void LookingGlassEffect::mouseChanged( const QPoint& pos, const QPoint& old, Qt::MouseButtons,
|
||||
Qt::MouseButtons, Qt::KeyboardModifiers, Qt::KeyboardModifiers )
|
||||
{
|
||||
if( pos != old && isEnabled() )
|
||||
if( pos != old && m_enabled )
|
||||
{
|
||||
effects->addRepaint( pos.x() - radius, pos.y() - radius, 2*radius, 2*radius );
|
||||
effects->addRepaint( old.x() - radius, old.y() - radius, 2*radius, 2*radius );
|
||||
}
|
||||
}
|
||||
|
||||
void LookingGlassEffect::postPaintScreen()
|
||||
{
|
||||
// Call the next effect.
|
||||
effects->postPaintScreen();
|
||||
if (m_valid && m_enabled) {
|
||||
// Disable render texture
|
||||
checkGLError("Before Pop Render Target");
|
||||
GLRenderTarget* target = effects->popRenderTarget();
|
||||
checkGLError("Pop Render Target");
|
||||
assert( target == m_fbo );
|
||||
Q_UNUSED( target );
|
||||
m_texture->bind();
|
||||
checkGLError("Bind Texture");
|
||||
|
||||
// Use the shader
|
||||
ShaderManager::instance()->pushShader(m_shader);
|
||||
m_shader->setUniform("u_zoom", (float)zoom);
|
||||
m_shader->setUniform("u_radius", (float)radius);
|
||||
checkGLError("Bind Shader");
|
||||
m_shader->setUniform("u_cursor", QVector2D(cursorPos().x(), cursorPos().y()));
|
||||
m_vbo->render(GL_TRIANGLES);
|
||||
checkGLError("Render VBO");
|
||||
ShaderManager::instance()->popShader();
|
||||
checkGLError("Pop Shader");
|
||||
m_texture->unbind();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "lookingglass.moc"
|
||||
|
|
|
@ -22,17 +22,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#ifndef KWIN_LOOKINGGLASS_H
|
||||
#define KWIN_LOOKINGGLASS_H
|
||||
|
||||
#include <kwinshadereffect.h>
|
||||
#include <kwineffects.h>
|
||||
|
||||
class KActionCollection;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class GLRenderTarget;
|
||||
class GLShader;
|
||||
class GLTexture;
|
||||
class GLVertexBuffer;
|
||||
|
||||
/**
|
||||
* Enhanced magnifier
|
||||
**/
|
||||
class LookingGlassEffect : public QObject, public ShaderEffect
|
||||
class LookingGlassEffect : public QObject, public Effect
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -45,6 +50,9 @@ class LookingGlassEffect : public QObject, public ShaderEffect
|
|||
Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers );
|
||||
|
||||
virtual void prePaintScreen( ScreenPrePaintData& data, int time );
|
||||
virtual void postPaintScreen();
|
||||
|
||||
static bool supported();
|
||||
|
||||
public slots:
|
||||
void toggle();
|
||||
|
@ -52,12 +60,19 @@ class LookingGlassEffect : public QObject, public ShaderEffect
|
|||
void zoomOut();
|
||||
|
||||
private:
|
||||
bool loadData();
|
||||
double zoom;
|
||||
double target_zoom;
|
||||
bool polling; // Mouse polling
|
||||
int radius;
|
||||
int initialradius;
|
||||
KActionCollection* actionCollection;
|
||||
GLTexture *m_texture;
|
||||
GLRenderTarget *m_fbo;
|
||||
GLVertexBuffer *m_vbo;
|
||||
GLShader *m_shader;
|
||||
bool m_enabled;
|
||||
bool m_valid;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in a new issue