diff --git a/effects/coverswitch/coverswitch.cpp b/effects/coverswitch/coverswitch.cpp
index 56c1a8df93..022a494c85 100644
--- a/effects/coverswitch/coverswitch.cpp
+++ b/effects/coverswitch/coverswitch.cpp
@@ -139,61 +139,6 @@ void CoverSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& d
effects->paintScreen(mask, region, data);
if (mActivated || stop || stopRequested) {
- QMatrix4x4 origProjection;
- QMatrix4x4 origModelview;
- ShaderManager *shaderManager = ShaderManager::instance();
- if (effects->numScreens() > 1) {
- // unfortunatelly we have to change the projection matrix in dual screen mode
- QRect fullRect = effects->clientArea(FullArea, activeScreen, effects->currentDesktop());
- float fovy = 60.0f;
- float aspect = 1.0f;
- float zNear = 0.1f;
- float zFar = 100.0f;
- float ymax = zNear * tan(fovy * M_PI / 360.0f);
- float ymin = -ymax;
- float xmin = ymin * aspect;
- float xmax = ymax * aspect;
- float xTranslate = 0.0;
- float yTranslate = 0.0;
- float xminFactor = 1.0;
- float xmaxFactor = 1.0;
- float yminFactor = 1.0;
- float ymaxFactor = 1.0;
- if (area.x() == 0 && area.width() != fullRect.width()) {
- // horizontal layout: left screen
- xminFactor = (float)area.width() / (float)fullRect.width();
- xmaxFactor = ((float)fullRect.width() - (float)area.width() * 0.5f) / ((float)fullRect.width() * 0.5f);
- xTranslate = (float)fullRect.width() * 0.5f - (float)area.width() * 0.5f;
- }
- if (area.x() != 0 && area.width() != fullRect.width()) {
- // horizontal layout: right screen
- xminFactor = ((float)fullRect.width() - (float)area.width() * 0.5f) / ((float)fullRect.width() * 0.5f);
- xmaxFactor = (float)area.width() / (float)fullRect.width();
- xTranslate = (float)fullRect.width() * 0.5f - (float)area.width() * 0.5f;
- }
- if (area.y() == 0 && area.height() != fullRect.height()) {
- // vertical layout: top screen
- yminFactor = ((float)fullRect.height() - (float)area.height() * 0.5f) / ((float)fullRect.height() * 0.5f);
- ymaxFactor = (float)area.height() / (float)fullRect.height();
- yTranslate = (float)fullRect.height() * 0.5f - (float)area.height() * 0.5f;
- }
- if (area.y() != 0 && area.height() != fullRect.height()) {
- // vertical layout: bottom screen
- yminFactor = (float)area.height() / (float)fullRect.height();
- ymaxFactor = ((float)fullRect.height() - (float)area.height() * 0.5f) / ((float)fullRect.height() * 0.5f);
- yTranslate = (float)fullRect.height() * 0.5f - (float)area.height() * 0.5f;
- }
- QMatrix4x4 projection;
- projection.frustum(xmin * xminFactor, xmax * xmaxFactor, ymin * yminFactor, ymax * ymaxFactor, zNear, zFar);
- QMatrix4x4 modelview;
- modelview.translate(xTranslate, yTranslate, 0.0);
- GLShader *shader = shaderManager->pushShader(ShaderManager::GenericShader);
- origProjection = shader->getUniformMatrix4x4("projection");
- origModelview = shader->getUniformMatrix4x4("modelview");
- shader->setUniform("projection", projection);
- shader->setUniform("modelview", origModelview * modelview);
- shaderManager->popShader();
- }
QList< EffectWindow* > tempList = currentWindowList;
int index = tempList.indexOf(selected_window);
@@ -296,7 +241,7 @@ void CoverSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& d
glEnable(GL_SCISSOR_TEST);
if (m_reflectionShader && m_reflectionShader->isValid()) {
- shaderManager->pushShader(m_reflectionShader);
+ ShaderManager::instance()->pushShader(m_reflectionShader);
QMatrix4x4 windowTransformation;
windowTransformation.translate(area.x() + area.width() * 0.5f, 0.0, 0.0);
m_reflectionShader->setUniform("windowTransformation", windowTransformation);
@@ -324,20 +269,13 @@ void CoverSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& d
vbo->setData(6, 3, verts.data(), texcoords.data());
vbo->render(GL_TRIANGLES);
- shaderManager->popShader();
+ ShaderManager::instance()->popShader();
}
glDisable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
}
paintScene(frontWindow, leftWindows, rightWindows);
- if (effects->numScreens() > 1) {
- GLShader *shader = shaderManager->pushShader(ShaderManager::GenericShader);
- shader->setUniform("projection", origProjection);
- shader->setUniform("modelview", origModelview);
- shaderManager->popShader();
- }
-
// Render the caption frame
if (windowTitle) {
double opacity = 1.0;
@@ -518,6 +456,62 @@ void CoverSwitchEffect::slotTabBoxAdded(int mode)
}
}
+ if (effects->numScreens() > 1) {
+ // unfortunatelly we have to change the projection matrix in dual screen mode
+ // code is adapted from SceneOpenGL2::createProjectionMatrix()
+ QRect fullRect = effects->clientArea(FullArea, activeScreen, effects->currentDesktop());
+ float fovy = 60.0f;
+ float aspect = 1.0f;
+ float zNear = 0.1f;
+ float zFar = 100.0f;
+
+ float ymax = zNear * std::tan(fovy * M_PI / 360.0f);
+ float ymin = -ymax;
+ float xmin = ymin * aspect;
+ float xmax = ymax * aspect;
+
+ if (area.width() != fullRect.width()) {
+ if (area.x() == 0) {
+ // horizontal layout: left screen
+ xmin *= (float)area.width() / (float)fullRect.width();
+ xmax *= (fullRect.width() - 0.5f * area.width()) / (0.5f * fullRect.width());
+ } else {
+ // horizontal layout: right screen
+ xmin *= (fullRect.width() - 0.5f * area.width()) / (0.5f * fullRect.width());
+ xmax *= (float)area.width() / (float)fullRect.width();
+ }
+ }
+ if (area.height() != fullRect.height()) {
+ if (area.y() == 0) {
+ // vertical layout: top screen
+ ymin *= (fullRect.height() - 0.5f * area.height()) / (0.5f * fullRect.height());
+ ymax *= (float)area.height() / (float)fullRect.height();
+ } else {
+ // vertical layout: bottom screen
+ ymin *= (float)area.height() / (float)fullRect.height();
+ ymax *= (fullRect.height() - 0.5f * area.height()) / (0.5f * fullRect.height());
+ }
+ }
+
+ m_projectionMatrix = QMatrix4x4();
+ m_projectionMatrix.frustum(xmin, xmax, ymin, ymax, zNear, zFar);
+
+ const float scaleFactor = 1.1f / zNear;
+
+ // Create a second matrix that transforms screen coordinates
+ // to world coordinates.
+ QMatrix4x4 matrix;
+ matrix.translate(xmin * scaleFactor, ymax * scaleFactor, -1.1);
+ matrix.scale( (xmax - xmin) * scaleFactor / fullRect.width(),
+ -(ymax - ymin) * scaleFactor / fullRect.height(),
+ 0.001);
+ // Combine the matrices
+ m_projectionMatrix *= matrix;
+
+ m_modelviewMatrix = QMatrix4x4();
+ m_modelviewMatrix.translate(area.x(), area.y(), 0.0);
+ }
+
// Setup caption frame geometry
if (windowTitle) {
QRect frameRect = QRect(area.width() * 0.25f + area.x(),
@@ -715,6 +709,10 @@ void CoverSwitchEffect::paintFrontWindow(EffectWindow* frontWindow, int width, i
return;
bool specialHandlingForward = false;
WindowPaintData data(frontWindow);
+ if (effects->numScreens() > 1) {
+ data.setProjectionMatrix(m_projectionMatrix);
+ data.setModelViewMatrix(m_modelviewMatrix);
+ }
data.setXTranslation(area.width() * 0.5 - frontWindow->geometry().x() - frontWindow->geometry().width() * 0.5);
if (leftWindows == 0) {
leftWindows = 1;
@@ -773,6 +771,10 @@ void CoverSwitchEffect::paintWindows(const EffectWindowList& windows, bool left,
// has to appear on this side after half of the time
if (animation && timeLine.currentValue() >= 0.5 && additionalWindow != NULL) {
WindowPaintData data(additionalWindow);
+ if (effects->numScreens() > 1) {
+ data.setProjectionMatrix(m_projectionMatrix);
+ data.setModelViewMatrix(m_modelviewMatrix);
+ }
data.setRotationAxis(Qt::YAxis);
data.setRotationAngle(angle * rotateFactor);
if (left) {
@@ -793,6 +795,10 @@ void CoverSwitchEffect::paintWindows(const EffectWindowList& windows, bool left,
continue;
}
WindowPaintData data(window);
+ if (effects->numScreens() > 1) {
+ data.setProjectionMatrix(m_projectionMatrix);
+ data.setModelViewMatrix(m_modelviewMatrix);
+ }
data.setRotationAxis(Qt::YAxis);
data.setRotationAngle(angle);
if (left)
diff --git a/effects/coverswitch/coverswitch.h b/effects/coverswitch/coverswitch.h
index 17307e4e49..b058db4d4d 100644
--- a/effects/coverswitch/coverswitch.h
+++ b/effects/coverswitch/coverswitch.h
@@ -157,6 +157,8 @@ private:
bool secondaryTabBox;
GLShader *m_reflectionShader;
+ QMatrix4x4 m_projectionMatrix;
+ QMatrix4x4 m_modelviewMatrix;
};
} // namespace
diff --git a/effects/flipswitch/flipswitch.cpp b/effects/flipswitch/flipswitch.cpp
index cdd57896fc..fd39b5032e 100644
--- a/effects/flipswitch/flipswitch.cpp
+++ b/effects/flipswitch/flipswitch.cpp
@@ -192,62 +192,6 @@ void FlipSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& da
}
}
- // multiscreen part taken from coverswitch.cpp
- // TODO: move to kwinglutils
- QMatrix4x4 origProjection;
- QMatrix4x4 origModelview;
- if (effects->numScreens() > 1) {
- // unfortunatelly we have to change the projection matrix in dual screen mode
- QRect fullRect = effects->clientArea(FullArea, effects->activeScreen(), effects->currentDesktop());
- float fovy = 60.0f;
- float aspect = 1.0f;
- float zNear = 0.1f;
- float zFar = 100.0f;
- float ymax = zNear * tan(fovy * M_PI / 360.0f);
- float ymin = -ymax;
- float xmin = ymin * aspect;
- float xmax = ymax * aspect;
- float xTranslate = 0.0;
- float yTranslate = 0.0;
- float xminFactor = 1.0;
- float xmaxFactor = 1.0;
- float yminFactor = 1.0;
- float ymaxFactor = 1.0;
- if (m_screenArea.x() == 0 && m_screenArea.width() != fullRect.width()) {
- // horizontal layout: left screen
- xminFactor = (float)m_screenArea.width() / (float)fullRect.width();
- xmaxFactor = ((float)fullRect.width() - (float)m_screenArea.width() * 0.5f) / ((float)fullRect.width() * 0.5f);
- xTranslate = (float)fullRect.width() * 0.5f - (float)m_screenArea.width() * 0.5f;
- }
- if (m_screenArea.x() != 0 && m_screenArea.width() != fullRect.width()) {
- // horizontal layout: right screen
- xminFactor = ((float)fullRect.width() - (float)m_screenArea.width() * 0.5f) / ((float)fullRect.width() * 0.5f);
- xmaxFactor = (float)m_screenArea.width() / (float)fullRect.width();
- xTranslate = (float)fullRect.width() * 0.5f - (float)m_screenArea.width() * 0.5f;
- }
- if (m_screenArea.y() == 0 && m_screenArea.height() != fullRect.height()) {
- // vertical layout: top screen
- yminFactor = ((float)fullRect.height() - (float)m_screenArea.height() * 0.5f) / ((float)fullRect.height() * 0.5f);
- ymaxFactor = (float)m_screenArea.height() / (float)fullRect.height();
- yTranslate = (float)fullRect.height() * 0.5f - (float)m_screenArea.height() * 0.5f;
- }
- if (m_screenArea.y() != 0 && m_screenArea.height() != fullRect.height()) {
- // vertical layout: bottom screen
- yminFactor = (float)m_screenArea.height() / (float)fullRect.height();
- ymaxFactor = ((float)fullRect.height() - (float)m_screenArea.height() * 0.5f) / ((float)fullRect.height() * 0.5f);
- yTranslate = (float)fullRect.height() * 0.5f - (float)m_screenArea.height() * 0.5f;
- }
- QMatrix4x4 projection;
- projection.frustum(xmin * xminFactor, xmax * xmaxFactor, ymin * yminFactor, ymax * ymaxFactor, zNear, zFar);
- QMatrix4x4 modelview;
- modelview.translate(xTranslate, yTranslate, 0.0);
- ShaderBinder binder(ShaderManager::GenericShader);
- GLShader *shader = binder.shader();
- origProjection = shader->getUniformMatrix4x4("projection");
- origModelview = shader->getUniformMatrix4x4("modelview");
- shader->setUniform("projection", projection);
- shader->setUniform("modelview", origModelview * modelview);
- }
int winMask = PAINT_WINDOW_TRANSFORMED | PAINT_WINDOW_TRANSLUCENT;
// fade in/out one window at the end of the stack during animation
@@ -255,6 +199,10 @@ void FlipSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& da
EffectWindow* w = m_flipOrderedWindows.last();
if (ItemInfo *info = m_windows.value(w,0)) {
WindowPaintData data(w);
+ if (effects->numScreens() > 1) {
+ data.setProjectionMatrix(m_projectionMatrix);
+ data.setModelViewMatrix(m_modelviewMatrix);
+ }
data.setRotationAxis(Qt::YAxis);
data.setRotationAngle(m_angle * m_startStopTimeLine.currentValue());
data.setOpacity(info->opacity);
@@ -286,6 +234,10 @@ void FlipSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& da
if (!info)
continue;
WindowPaintData data(w);
+ if (effects->numScreens() > 1) {
+ data.setProjectionMatrix(m_projectionMatrix);
+ data.setModelViewMatrix(m_modelviewMatrix);
+ }
data.setRotationAxis(Qt::YAxis);
data.setRotationAngle(m_angle * m_startStopTimeLine.currentValue());
data.setOpacity(info->opacity);
@@ -342,13 +294,6 @@ void FlipSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& da
effects->drawWindow(w, winMask, infiniteRegion(), data);
}
- if (effects->numScreens() > 1) {
- ShaderBinder binder(ShaderManager::GenericShader);
- GLShader *shader = binder.shader();
- shader->setUniform("projection", origProjection);
- shader->setUniform("modelview", origModelview);
- }
-
if (m_windowTitle) {
// Render the caption frame
if (m_animation) {
@@ -581,6 +526,62 @@ void FlipSwitchEffect::setActive(bool activate, FlipSwitchMode mode)
m_activeScreen = effects->activeScreen();
m_screenArea = effects->clientArea(ScreenArea, m_activeScreen, effects->currentDesktop());
+ if (effects->numScreens() > 1) {
+ // unfortunatelly we have to change the projection matrix in dual screen mode
+ // code is copied from Coverswitch
+ QRect fullRect = effects->clientArea(FullArea, m_activeScreen, effects->currentDesktop());
+ float fovy = 60.0f;
+ float aspect = 1.0f;
+ float zNear = 0.1f;
+ float zFar = 100.0f;
+
+ float ymax = zNear * std::tan(fovy * M_PI / 360.0f);
+ float ymin = -ymax;
+ float xmin = ymin * aspect;
+ float xmax = ymax * aspect;
+
+ if (m_screenArea.width() != fullRect.width()) {
+ if (m_screenArea.x() == 0) {
+ // horizontal layout: left screen
+ xmin *= (float)m_screenArea.width() / (float)fullRect.width();
+ xmax *= (fullRect.width() - 0.5f * m_screenArea.width()) / (0.5f * fullRect.width());
+ } else {
+ // horizontal layout: right screen
+ xmin *= (fullRect.width() - 0.5f * m_screenArea.width()) / (0.5f * fullRect.width());
+ xmax *= (float)m_screenArea.width() / (float)fullRect.width();
+ }
+ }
+ if (m_screenArea.height() != fullRect.height()) {
+ if (m_screenArea.y() == 0) {
+ // vertical layout: top screen
+ ymin *= (fullRect.height() - 0.5f * m_screenArea.height()) / (0.5f * fullRect.height());
+ ymax *= (float)m_screenArea.height() / (float)fullRect.height();
+ } else {
+ // vertical layout: bottom screen
+ ymin *= (float)m_screenArea.height() / (float)fullRect.height();
+ ymax *= (fullRect.height() - 0.5f * m_screenArea.height()) / (0.5f * fullRect.height());
+ }
+ }
+
+ m_projectionMatrix = QMatrix4x4();
+ m_projectionMatrix.frustum(xmin, xmax, ymin, ymax, zNear, zFar);
+
+ const float scaleFactor = 1.1f / zNear;
+
+ // Create a second matrix that transforms screen coordinates
+ // to world coordinates.
+ QMatrix4x4 matrix;
+ matrix.translate(xmin * scaleFactor, ymax * scaleFactor, -1.1);
+ matrix.scale( (xmax - xmin) * scaleFactor / fullRect.width(),
+ -(ymax - ymin) * scaleFactor / fullRect.height(),
+ 0.001);
+ // Combine the matrices
+ m_projectionMatrix *= matrix;
+
+ m_modelviewMatrix = QMatrix4x4();
+ m_modelviewMatrix.translate(m_screenArea.x(), m_screenArea.y(), 0.0);
+ }
+
if (m_stop) {
// effect is still closing from last usage
m_stop = false;
diff --git a/effects/flipswitch/flipswitch.h b/effects/flipswitch/flipswitch.h
index 058e6b3835..859f30c65f 100644
--- a/effects/flipswitch/flipswitch.h
+++ b/effects/flipswitch/flipswitch.h
@@ -22,6 +22,7 @@ along with this program. If not, see .
#define KWIN_FLIPSWITCH_H
#include
+#include
#include
#include
@@ -133,6 +134,8 @@ private:
QFont m_captionFont;
EffectWindowList m_flipOrderedWindows;
QHash< const EffectWindow*, ItemInfo* > m_windows;
+ QMatrix4x4 m_projectionMatrix;
+ QMatrix4x4 m_modelviewMatrix;
// options
bool m_tabbox;
bool m_tabboxAlternative;