void CoverSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) { effects->paintScreen(mask, region, data); if (mActivated || stop || stopRequested) { QList< EffectWindow* > tempList = currentWindowList; int index = tempList.indexOf(selected_window); if (animation || start || stop) { if (!start && !stop) { if (direction == Right) index++; else index--; if (index < 0) index = tempList.count() + index; if (index >= tempList.count()) index = index % tempList.count(); } foreach (Direction direction, scheduled_directions) { if (direction == Right) index++; else index--; if (index < 0) index = tempList.count() + index; if (index >= tempList.count()) index = index % tempList.count(); } } int leftIndex = index - 1; if (leftIndex < 0) leftIndex = tempList.count() - 1; int rightIndex = index + 1; if (rightIndex == tempList.count()) rightIndex = 0; EffectWindow* frontWindow = tempList[ index ]; leftWindows.clear(); rightWindows.clear(); bool evenWindows = (tempList.count() % 2 == 0) ? true : false; int leftWindowCount = 0; if (evenWindows) leftWindowCount = tempList.count() / 2 - 1; else leftWindowCount = (tempList.count() - 1) / 2; for (int i = 0; i < leftWindowCount; i++) { int tempIndex = (leftIndex - i); if (tempIndex < 0) tempIndex = tempList.count() + tempIndex; leftWindows.prepend(tempList[ tempIndex ]); } int rightWindowCount = 0; if (evenWindows) rightWindowCount = tempList.count() / 2; else rightWindowCount = (tempList.count() - 1) / 2; for (int i = 0; i < rightWindowCount; i++) { int tempIndex = (rightIndex + i) % tempList.count(); rightWindows.prepend(tempList[ tempIndex ]); } if (reflection) { // no reflections during start and stop animation // except when using a shader if ((!start && !stop) || effects->compositingType() == OpenGL2Compositing) paintScene(frontWindow, leftWindows, rightWindows, true); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // we can use a huge scale factor (needed to calculate the rearground vertices) // as we restrict with a PaintClipper painting on the current screen float reflectionScaleFactor = 100000 * tan(60.0 * M_PI / 360.0f) / area.width(); const float width = area.width(); const float height = area.height(); float vertices[] = { -width * 0.5f, height, 0.0, width * 0.5f, height, 0.0, width*reflectionScaleFactor, height, -5000, -width*reflectionScaleFactor, height, -5000 }; // foreground if (start) { mirrorColor[0][3] = timeLine.currentValue(); } else if (stop) { mirrorColor[0][3] = 1.0 - timeLine.currentValue(); } else { mirrorColor[0][3] = 1.0; } int y = 0; // have to adjust the y values to fit OpenGL // in OpenGL y==0 is at bottom, in Qt at top if (effects->numScreens() > 1) { QRect fullArea = effects->clientArea(FullArea, 0, 1); if (fullArea.height() != area.height()) { if (area.y() == 0) y = fullArea.height() - area.height(); else y = fullArea.height() - area.y() - area.height(); } } // use scissor to restrict painting of the reflection plane to current screen glScissor(area.x(), y, area.width(), area.height()); glEnable(GL_SCISSOR_TEST); if (m_reflectionShader && m_reflectionShader->isValid()) { ShaderManager::instance()->pushShader(m_reflectionShader); QMatrix4x4 windowTransformation = data.projectionMatrix(); windowTransformation.translate(area.x() + area.width() * 0.5f, 0.0, 0.0); m_reflectionShader->setUniform(GLShader::ModelViewProjectionMatrix, windowTransformation); m_reflectionShader->setUniform("u_frontColor", QVector4D(mirrorColor[0][0], mirrorColor[0][1], mirrorColor[0][2], mirrorColor[0][3])); m_reflectionShader->setUniform("u_backColor", QVector4D(mirrorColor[1][0], mirrorColor[1][1], mirrorColor[1][2], mirrorColor[1][3])); // TODO: make this one properly QVector<float> verts; QVector<float> texcoords; verts.reserve(18); texcoords.reserve(12); texcoords << 1.0 << 0.0; verts << vertices[6] << vertices[7] << vertices[8]; texcoords << 1.0 << 0.0; verts << vertices[9] << vertices[10] << vertices[11]; texcoords << 0.0 << 0.0; verts << vertices[0] << vertices[1] << vertices[2]; texcoords << 0.0 << 0.0; verts << vertices[0] << vertices[1] << vertices[2]; texcoords << 0.0 << 0.0; verts << vertices[3] << vertices[4] << vertices[5]; texcoords << 1.0 << 0.0; verts << vertices[6] << vertices[7] << vertices[8]; GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); vbo->reset(); vbo->setData(6, 3, verts.data(), texcoords.data()); vbo->render(GL_TRIANGLES); ShaderManager::instance()->popShader(); } glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); } paintScene(frontWindow, leftWindows, rightWindows); // Render the caption frame if (windowTitle) { double opacity = 1.0; if (start) opacity = timeLine.currentValue(); else if (stop) opacity = 1.0 - timeLine.currentValue(); if (animation) captionFrame->setCrossFadeProgress(timeLine.currentValue()); captionFrame->render(region, opacity); } }