void Scene::paintCB(UPaintEvent& e) { // client GL graphics can be performed until the current function returns GLSection gls(this); if (is_initialized) ::g.render.camera(); paintScene(); }
void CoverSwitchEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) { 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); if (shaderManager->isShaderBound()) { 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(); } else { #ifndef KWIN_HAVE_OPENGLES glMatrixMode(GL_PROJECTION); pushMatrix(); loadMatrix(projection); glMatrixMode(GL_MODELVIEW); pushMatrix(modelview); #endif } } 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) || ShaderManager::instance()->isValid()) paintScene(frontWindow, leftWindows, rightWindows, true); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); #ifndef KWIN_HAVE_OPENGLES glPolygonMode(GL_FRONT, GL_FILL); #endif QRect fullRect = effects->clientArea(FullArea, activeScreen, effects->currentDesktop()); // 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(); float vertices[] = { -area.width() * 0.5f, area.height(), 0.0, area.width() * 0.5f, area.height(), 0.0, (float)area.width()*reflectionScaleFactor, area.height(), -5000, -(float)area.width()*reflectionScaleFactor, area.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 (shaderManager->isValid() && m_reflectionShader->isValid()) { shaderManager->pushShader(m_reflectionShader); QMatrix4x4 windowTransformation; windowTransformation.translate(area.x() + area.width() * 0.5f, 0.0, 0.0); m_reflectionShader->setUniform("windowTransformation", 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->popShader(); } else { #ifndef KWIN_HAVE_OPENGLES glPushMatrix(); if (effects->numScreens() > 1 && area.x() != fullRect.x()) { // have to change the reflection area in horizontal layout and right screen glTranslatef(-area.x(), 0.0, 0.0); } glTranslatef(area.x() + area.width() * 0.5f, 0.0, 0.0); glColor4fv(mirrorColor[0]); glBegin(GL_POLYGON); glVertex3f(vertices[0], vertices[1], vertices[2]); glVertex3f(vertices[3], vertices[4], vertices[5]); // rearground glColor4fv(mirrorColor[1]); glVertex3f(vertices[6], vertices[7], vertices[8]); glVertex3f(vertices[9], vertices[10], vertices[11]); glEnd(); glPopMatrix(); #endif } glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); } paintScene(frontWindow, leftWindows, rightWindows); if (effects->numScreens() > 1) { if (shaderManager->isShaderBound()) { GLShader *shader = shaderManager->pushShader(ShaderManager::GenericShader); shader->setUniform("projection", origProjection); shader->setUniform("modelview", origModelview); shaderManager->popShader(); } else { #ifndef KWIN_HAVE_OPENGLES popMatrix(); // revert change of projection matrix glMatrixMode(GL_PROJECTION); popMatrix(); glMatrixMode(GL_MODELVIEW); #endif } } // 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); } if ((thumbnails && (!dynamicThumbnails || (dynamicThumbnails && currentWindowList.size() >= thumbnailWindows))) && !(start || stop)) { BoxSwitchEffectProxy *proxy = static_cast<BoxSwitchEffectProxy*>(effects->getProxy("boxswitch")); if (proxy) proxy->paintWindowsBox(region); } }
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; windowTransformation.translate(area.x() + area.width() * 0.5f, 0.0, 0.0); m_reflectionShader->setUniform("windowTransformation", 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); } }
void Window::paint() const { paintScene(); SwapBuffers(m_deviceContext); }