File indexing completed on 2025-03-09 03:52:07
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2004-01-19 0007 * Description : a presentation tool. 0008 * 0009 * SPDX-FileCopyrightText: 2004 by Renchi Raju <renchi dot raju at gmail dot com> 0010 * SPDX-FileCopyrightText: 2006-2009 by Valerio Fuoglio <valerio.fuoglio@gmail.com> 0011 * SPDX-FileCopyrightText: 2009 by Andi Clemens <andi dot clemens at googlemail dot com> 0012 * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0013 * SPDX-FileCopyrightText: 2021 by Phuoc Khanh Le <phuockhanhnk94 at gmail dot com> 0014 * 0015 * SPDX-License-Identifier: GPL-2.0-or-later 0016 * 0017 * ============================================================ */ 0018 0019 #include "presentationgl.h" 0020 0021 // C++ includes 0022 0023 #include <cmath> 0024 #include <cstdlib> 0025 0026 // Qt includes 0027 0028 #include <QCursor> 0029 #include <QScreen> 0030 #include <QWindow> 0031 #include <QEvent> 0032 #include <QFileInfo> 0033 #include <QFontMetrics> 0034 #include <QImage> 0035 #include <QPainter> 0036 #include <QPainterPath> 0037 #include <QPainterPathStroker> 0038 #include <QPixmap> 0039 #include <QTimer> 0040 #include <QApplication> 0041 #include <QOpenGLTexture> 0042 0043 // KDE includes 0044 0045 #include <klocalizedstring.h> 0046 0047 // Local includes 0048 0049 #include "digikam_config.h" 0050 #include "digikam_debug.h" 0051 #include "presentationcontainer.h" 0052 #include "presentationctrlwidget.h" 0053 #include "presentationloader.h" 0054 0055 // OpenGL headers is not included automatically with ARM targets 0056 0057 #ifdef Q_PROCESSOR_ARM 0058 # include <GL/gl.h> 0059 #endif 0060 0061 #ifdef HAVE_MEDIAPLAYER 0062 # include "presentationaudiowidget.h" 0063 #endif 0064 0065 using namespace Digikam; 0066 0067 namespace DigikamGenericPresentationPlugin 0068 { 0069 0070 class Q_DECL_HIDDEN PresentationGL::Private 0071 { 0072 0073 public: 0074 0075 explicit Private() 0076 : timer (nullptr), 0077 fileIndex (0), 0078 imageLoader (nullptr), 0079 tex1First (true), 0080 curr (0), 0081 width (0), 0082 height (0), 0083 xMargin (0), 0084 yMargin (0), 0085 effect (nullptr), 0086 effectRunning (false), 0087 timeout (0), 0088 random (false), 0089 endOfShow (false), 0090 i (0), 0091 dir (0), 0092 slideCtrlWidget (nullptr), 0093 0094 #ifdef HAVE_MEDIAPLAYER 0095 0096 playbackWidget (nullptr), 0097 0098 #endif 0099 0100 mouseMoveTimer (nullptr), 0101 deskX (0), 0102 deskY (0), 0103 deskWidth (0), 0104 deskHeight (0), 0105 sharedData (nullptr), 0106 randomGenerator (QRandomGenerator::global()) 0107 { 0108 texture[0] = nullptr; 0109 texture[1] = nullptr; 0110 texture[2] = nullptr; 0111 } 0112 0113 QMap<QString, EffectMethod> effects; 0114 0115 QTimer* timer; 0116 int fileIndex; 0117 0118 PresentationLoader* imageLoader; 0119 QOpenGLTexture* texture[3]; 0120 bool tex1First; 0121 int curr; 0122 0123 int width; 0124 int height; 0125 int xMargin; 0126 int yMargin; 0127 0128 0129 EffectMethod effect; 0130 bool effectRunning; 0131 int timeout; 0132 bool random; 0133 bool endOfShow; 0134 0135 int i; 0136 int dir; 0137 float points[40][40][3] = { { { 0.0 } } }; 0138 0139 PresentationCtrlWidget* slideCtrlWidget; 0140 0141 #ifdef HAVE_MEDIAPLAYER 0142 0143 PresentationAudioWidget* playbackWidget; 0144 0145 #endif 0146 0147 QTimer* mouseMoveTimer; 0148 0149 int deskX; 0150 int deskY; 0151 int deskWidth; 0152 int deskHeight; 0153 0154 PresentationContainer* sharedData; 0155 0156 QRandomGenerator* randomGenerator; 0157 }; 0158 0159 PresentationGL::PresentationGL(PresentationContainer* const sharedData) 0160 : QOpenGLWidget(), 0161 d (new Private) 0162 { 0163 setAttribute(Qt::WA_DeleteOnClose); 0164 setContextMenuPolicy(Qt::PreventContextMenu); 0165 0166 #ifdef Q_OS_WIN 0167 0168 setWindowFlags(Qt::Popup | 0169 Qt::FramelessWindowHint | 0170 Qt::WindowStaysOnTopHint); 0171 0172 #else 0173 0174 setWindowState(windowState() | Qt::WindowFullScreen); 0175 0176 #endif 0177 0178 QScreen* screen = qApp->primaryScreen(); 0179 0180 if (QWidget* const widget = qApp->activeWindow()) 0181 { 0182 if (QWindow* const window = widget->windowHandle()) 0183 { 0184 screen = window->screen(); 0185 } 0186 } 0187 0188 QRect deskRect = screen->geometry(); 0189 d->deskX = deskRect.x(); 0190 d->deskY = deskRect.y(); 0191 d->deskWidth = deskRect.width(); 0192 d->deskHeight = deskRect.height(); 0193 0194 move(d->deskX, d->deskY); 0195 resize(d->deskWidth, d->deskHeight); 0196 0197 d->sharedData = sharedData; 0198 d->sharedData->display = this; 0199 0200 d->slideCtrlWidget = new PresentationCtrlWidget(this, d->sharedData); 0201 d->slideCtrlWidget->hide(); 0202 0203 if (!d->sharedData->loop) 0204 { 0205 d->slideCtrlWidget->setEnabledPrev(false); 0206 } 0207 0208 connect(d->slideCtrlWidget, SIGNAL(signalPause()), 0209 this, SLOT(slotPause())); 0210 0211 connect(d->slideCtrlWidget, SIGNAL(signalPlay()), 0212 this, SLOT(slotPlay())); 0213 0214 connect(d->slideCtrlWidget, SIGNAL(signalNext()), 0215 this, SLOT(slotNext())); 0216 0217 connect(d->slideCtrlWidget, SIGNAL(signalPrev()), 0218 this, SLOT(slotPrev())); 0219 0220 connect(d->slideCtrlWidget, SIGNAL(signalClose()), 0221 this, SLOT(slotClose())); 0222 0223 #ifdef HAVE_MEDIAPLAYER 0224 0225 d->playbackWidget = new PresentationAudioWidget(this, d->sharedData->soundtrackUrls, d->sharedData); 0226 d->playbackWidget->hide(); 0227 d->playbackWidget->move(d->deskX, d->deskY); 0228 0229 #endif 0230 0231 int w = d->slideCtrlWidget->width() - 1; 0232 d->slideCtrlWidget->move(d->deskX + d->deskWidth - w, d->deskY); 0233 0234 // -- Minimal texture size (opengl specs) -------------- 0235 0236 d->width = 64; 0237 d->height = 64; 0238 0239 // -- Margin ------------------------------------------- 0240 0241 d->xMargin = int (d->deskWidth / d->width); 0242 d->yMargin = int (d->deskWidth / d->height); 0243 0244 // ------------------------------------------------------------------ 0245 0246 d->fileIndex = -1; // start with -1 0247 d->timeout = d->sharedData->delay; 0248 d->imageLoader = new PresentationLoader(d->sharedData, width(), height(), d->fileIndex); 0249 0250 // -------------------------------------------------- 0251 0252 registerEffects(); 0253 0254 if (d->sharedData->effectNameGL == QLatin1String("Random")) 0255 { 0256 d->effect = getRandomEffect(); 0257 d->random = true; 0258 } 0259 else 0260 { 0261 d->effect = d->effects[d->sharedData->effectNameGL]; 0262 0263 if (!d->effect) 0264 { 0265 d->effect = d->effects[QLatin1String("None")]; 0266 } 0267 0268 d->random = false; 0269 } 0270 0271 // -------------------------------------------------- 0272 0273 d->timer = new QTimer(this); 0274 0275 connect(d->timer, SIGNAL(timeout()), 0276 this, SLOT(slotTimeOut())); 0277 0278 d->timer->setSingleShot(true); 0279 d->timer->start(500); 0280 0281 // -- hide cursor when not moved -------------------- 0282 0283 d->mouseMoveTimer = new QTimer(this); 0284 d->mouseMoveTimer->setSingleShot(true); 0285 0286 connect(d->mouseMoveTimer, SIGNAL(timeout()), 0287 this, SLOT(slotMouseMoveTimeOut())); 0288 0289 setMouseTracking(true); 0290 slotMouseMoveTimeOut(); 0291 0292 #ifdef HAVE_MEDIAPLAYER 0293 0294 if (d->sharedData->soundtrackPlay) 0295 { 0296 d->playbackWidget->slotPlay(); 0297 } 0298 0299 #endif 0300 0301 } 0302 0303 PresentationGL::~PresentationGL() 0304 { 0305 0306 #ifdef HAVE_MEDIAPLAYER 0307 0308 d->playbackWidget->slotStop(); 0309 0310 #endif 0311 0312 d->timer->stop(); 0313 d->mouseMoveTimer->stop(); 0314 0315 d->texture[0]->destroy(); 0316 d->texture[1]->destroy(); 0317 d->texture[2]->destroy(); 0318 0319 delete d->texture[0]; 0320 delete d->texture[1]; 0321 delete d->texture[2]; 0322 delete d->imageLoader; 0323 delete d; 0324 } 0325 0326 void PresentationGL::initializeGL() 0327 { 0328 // Enable Texture Mapping 0329 0330 glEnable(GL_TEXTURE_2D); 0331 0332 // Clear The Background Color 0333 0334 glClearColor(0.0, 0.0, 0.0, 1.0f); 0335 0336 // Turn Blending On 0337 0338 glEnable(GL_BLEND); 0339 0340 // Blending Function For Translucency Based On Source Alpha Value 0341 0342 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 0343 0344 // Enable perspective vision 0345 0346 glClearDepth(1.0f); 0347 0348 // get the maximum texture value. 0349 0350 GLint maxTexVal; 0351 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexVal); 0352 0353 // allow only maximum texture value of 1024. anything bigger and things slow down 0354 0355 maxTexVal = qMin(1024, maxTexVal); 0356 0357 d->width = d->deskWidth; 0358 d->height = d->deskHeight; 0359 0360 d->width = 1 << (int)ceil(log((float)d->width) / log((float)2)) ; 0361 d->height = 1 << (int)ceil(log((float)d->height) / log((float)2)); 0362 0363 d->width = qMin(maxTexVal, d->width); 0364 d->height = qMin(maxTexVal, d->height); 0365 0366 d->texture[0] = new QOpenGLTexture(QOpenGLTexture::Target2D); 0367 d->texture[1] = new QOpenGLTexture(QOpenGLTexture::Target2D); 0368 d->texture[2] = new QOpenGLTexture(QOpenGLTexture::Target2D); // end screen texture 0369 0370 QImage black(width(), height(), QImage::Format_RGB32); 0371 black.fill(QColor(0, 0, 0).rgb()); 0372 0373 d->texture[0]->setData(black); 0374 d->texture[0]->bind(); 0375 } 0376 0377 void PresentationGL::paintGL() 0378 { 0379 glDisable(GL_DEPTH_TEST); 0380 0381 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 0382 glLoadIdentity(); 0383 0384 glMatrixMode(GL_PROJECTION); 0385 glLoadIdentity(); 0386 0387 glMatrixMode(GL_MODELVIEW); 0388 glLoadIdentity(); 0389 0390 if (d->endOfShow) 0391 { 0392 showEndOfShow(); 0393 } 0394 else 0395 { 0396 if (d->effectRunning && d->effect) 0397 { 0398 (this->*d->effect)(); 0399 } 0400 else 0401 { 0402 paintTexture(); 0403 } 0404 } 0405 } 0406 0407 void PresentationGL::resizeGL(int w, int h) 0408 { 0409 // Reset The Current Viewport And Perspective Transformation 0410 0411 glViewport(0, 0, (GLint)w, (GLint)h); 0412 0413 glMatrixMode(GL_PROJECTION); 0414 glLoadIdentity(); 0415 } 0416 0417 void PresentationGL::keyPressEvent(QKeyEvent* event) 0418 { 0419 if (!event) 0420 { 0421 return; 0422 } 0423 0424 d->slideCtrlWidget->keyPressEvent(event); 0425 0426 #ifdef HAVE_MEDIAPLAYER 0427 0428 d->playbackWidget->keyPressEvent(event); 0429 0430 #endif 0431 0432 } 0433 0434 void PresentationGL::mousePressEvent(QMouseEvent* e) 0435 { 0436 if (d->endOfShow) 0437 { 0438 slotClose(); 0439 } 0440 0441 if (e->button() == Qt::LeftButton) 0442 { 0443 d->timer->stop(); 0444 d->slideCtrlWidget->setPaused(!d->sharedData->offAutoDelay); 0445 slotNext(); 0446 } 0447 else if ((e->button() == Qt::RightButton) && ((d->fileIndex - 1) >= 0)) 0448 { 0449 d->timer->stop(); 0450 d->slideCtrlWidget->setPaused(!d->sharedData->offAutoDelay); 0451 slotPrev(); 0452 } 0453 } 0454 0455 void PresentationGL::mouseMoveEvent(QMouseEvent* e) 0456 { 0457 setCursor(QCursor(Qt::ArrowCursor)); 0458 d->mouseMoveTimer->start(1000); 0459 0460 if (!d->slideCtrlWidget->canHide() 0461 0462 #ifdef HAVE_MEDIAPLAYER 0463 0464 || !d->playbackWidget->canHide() 0465 0466 #endif 0467 0468 ) 0469 { 0470 return; 0471 } 0472 0473 QPoint pos(e->pos()); 0474 0475 if ((pos.y() > 20) && 0476 (pos.y() < (d->deskHeight - 20 - 1))) 0477 { 0478 if (d->slideCtrlWidget->isHidden() 0479 0480 #ifdef HAVE_MEDIAPLAYER 0481 0482 || d->playbackWidget->isHidden() 0483 0484 #endif 0485 0486 ) 0487 { 0488 return; 0489 } 0490 else 0491 { 0492 hideOverlays(); 0493 setFocus(); 0494 } 0495 0496 return; 0497 } 0498 0499 showOverlays(); 0500 } 0501 0502 void PresentationGL::wheelEvent(QWheelEvent* e) 0503 { 0504 if (!d->sharedData->enableMouseWheel) 0505 { 0506 return; 0507 } 0508 0509 if (d->endOfShow) 0510 { 0511 slotClose(); 0512 } 0513 0514 int delta = e->angleDelta().y(); 0515 0516 if (delta < 0) 0517 { 0518 d->timer->stop(); 0519 d->slideCtrlWidget->setPaused(true); 0520 slotNext(); 0521 } 0522 else if ((delta > 0) && ((d->fileIndex - 1) >= 0)) 0523 { 0524 d->timer->stop(); 0525 d->slideCtrlWidget->setPaused(true); 0526 slotPrev(); 0527 } 0528 } 0529 0530 void PresentationGL::registerEffects() 0531 { 0532 d->effects.insert(QLatin1String("None"), &PresentationGL::effectNone); 0533 d->effects.insert(QLatin1String("Blend"), &PresentationGL::effectBlend); 0534 d->effects.insert(QLatin1String("Fade"), &PresentationGL::effectFade); 0535 d->effects.insert(QLatin1String("Rotate"), &PresentationGL::effectRotate); 0536 d->effects.insert(QLatin1String("Bend"), &PresentationGL::effectBend); 0537 d->effects.insert(QLatin1String("In Out"), &PresentationGL::effectInOut); 0538 d->effects.insert(QLatin1String("Slide"), &PresentationGL::effectSlide); 0539 d->effects.insert(QLatin1String("Flutter"), &PresentationGL::effectFlutter); 0540 d->effects.insert(QLatin1String("Cube"), &PresentationGL::effectCube); 0541 } 0542 0543 QStringList PresentationGL::effectNames() 0544 { 0545 QStringList effects; 0546 0547 effects.append(QLatin1String("None")); 0548 effects.append(QLatin1String("Bend")); 0549 effects.append(QLatin1String("Blend")); 0550 effects.append(QLatin1String("Cube")); 0551 effects.append(QLatin1String("Fade")); 0552 effects.append(QLatin1String("Flutter")); 0553 effects.append(QLatin1String("In Out")); 0554 effects.append(QLatin1String("Rotate")); 0555 effects.append(QLatin1String("Slide")); 0556 effects.append(QLatin1String("Random")); 0557 0558 return effects; 0559 } 0560 0561 QMap<QString, QString> PresentationGL::effectNamesI18N() 0562 { 0563 QMap<QString, QString> effects; 0564 0565 effects[QLatin1String("None")] = i18nc("Filter Effect: No effect", "None"); 0566 effects[QLatin1String("Bend")] = i18nc("Filter Effect: Bend", "Bend"); 0567 effects[QLatin1String("Blend")] = i18nc("Filter Effect: Blend", "Blend"); 0568 effects[QLatin1String("Cube")] = i18nc("Filter Effect: Cube", "Cube"); 0569 effects[QLatin1String("Fade")] = i18nc("Filter Effect: Fade", "Fade"); 0570 effects[QLatin1String("Flutter")] = i18nc("Filter Effect: Flutter", "Flutter"); 0571 effects[QLatin1String("In Out")] = i18nc("Filter Effect: In Out", "In Out"); 0572 effects[QLatin1String("Rotate")] = i18nc("Filter Effect: Rotate", "Rotate"); 0573 effects[QLatin1String("Slide")] = i18nc("Filter Effect: Slide", "Slide"); 0574 effects[QLatin1String("Random")] = i18nc("Filter Effect: Random effect", "Random"); 0575 0576 return effects; 0577 } 0578 0579 PresentationGL::EffectMethod PresentationGL::getRandomEffect() 0580 { 0581 QMap<QString, EffectMethod> tmpMap(d->effects); 0582 0583 tmpMap.remove(QLatin1String("None")); 0584 QStringList t = tmpMap.keys(); 0585 int count = t.count(); 0586 int i = d->randomGenerator->bounded(count); 0587 QString key = t[i]; 0588 0589 return tmpMap[key]; 0590 } 0591 0592 void PresentationGL::advanceFrame() 0593 { 0594 d->fileIndex++; 0595 d->imageLoader->next(); 0596 int num = d->sharedData->urlList.count(); 0597 0598 if (d->fileIndex >= num) 0599 { 0600 if (d->sharedData->loop) 0601 { 0602 d->fileIndex = 0; 0603 } 0604 else 0605 { 0606 d->fileIndex = num - 1; 0607 d->endOfShow = true; 0608 d->slideCtrlWidget->setEnabledPlay(false); 0609 d->slideCtrlWidget->setEnabledNext(false); 0610 d->slideCtrlWidget->setEnabledPrev(false); 0611 } 0612 } 0613 0614 if (!d->sharedData->loop && !d->endOfShow) 0615 { 0616 d->slideCtrlWidget->setEnabledPrev(d->fileIndex > 0); 0617 d->slideCtrlWidget->setEnabledNext(d->fileIndex < (num - 1)); 0618 } 0619 0620 d->tex1First = !d->tex1First; 0621 d->curr = (d->curr == 0) ? 1 : 0; 0622 } 0623 0624 void PresentationGL::previousFrame() 0625 { 0626 d->fileIndex--; 0627 d->imageLoader->prev(); 0628 int num = d->sharedData->urlList.count(); 0629 0630 if (d->fileIndex < 0) 0631 { 0632 if (d->sharedData->loop) 0633 { 0634 d->fileIndex = num - 1; 0635 } 0636 else 0637 { 0638 d->fileIndex = 0; 0639 d->endOfShow = true; 0640 d->slideCtrlWidget->setEnabledPlay(false); 0641 d->slideCtrlWidget->setEnabledNext(false); 0642 d->slideCtrlWidget->setEnabledPrev(false); 0643 } 0644 } 0645 0646 if (!d->sharedData->loop && !d->endOfShow) 0647 { 0648 d->slideCtrlWidget->setEnabledPrev(d->fileIndex > 0); 0649 d->slideCtrlWidget->setEnabledNext(d->fileIndex < (num - 1)); 0650 } 0651 0652 d->tex1First = !d->tex1First; 0653 d->curr = (d->curr == 0) ? 1 : 0; 0654 } 0655 0656 void PresentationGL::loadImage() 0657 { 0658 QImage image = d->imageLoader->getCurrent(); 0659 int a = d->tex1First ? 0 : 1; 0660 0661 if (!image.isNull()) 0662 { 0663 QImage black(width(), height(), QImage::Format_RGB32); 0664 0665 black.fill(QColor(0, 0, 0).rgb()); 0666 0667 montage(image, black); 0668 0669 if (!d->sharedData->openGlFullScale) 0670 { 0671 black = black.scaled(d->width, d->height, 0672 Qt::IgnoreAspectRatio, 0673 Qt::SmoothTransformation); 0674 } 0675 0676 if (d->sharedData->printFileName) 0677 { 0678 printFilename(black); 0679 } 0680 0681 if (d->sharedData->printProgress) 0682 { 0683 printProgress(black); 0684 } 0685 0686 if (d->sharedData->printFileComments) 0687 { 0688 printComments(black); 0689 } 0690 0691 /* create the texture */ 0692 0693 d->texture[a]->destroy(); 0694 d->texture[a]->setData(black.mirrored()); 0695 d->texture[a]->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); 0696 d->texture[a]->setMagnificationFilter(QOpenGLTexture::Linear); 0697 d->texture[a]->bind(); 0698 } 0699 } 0700 0701 void PresentationGL::montage(QImage& top, QImage& bot) 0702 { 0703 int tw = top.width(); 0704 int th = top.height(); 0705 int bw = bot.width(); 0706 int bh = bot.height(); 0707 0708 if ((tw > bw) || (th > bh)) 0709 { 0710 qFatal("Top Image should be smaller or same size as Bottom Image"); 0711 } 0712 0713 if (top.depth() != 32) 0714 { 0715 top = top.convertToFormat(QImage::Format_RGB32); 0716 } 0717 0718 if (bot.depth() != 32) 0719 { 0720 bot = bot.convertToFormat(QImage::Format_RGB32); 0721 } 0722 0723 int sw = bw / 2 - tw / 2; // int ew = bw/2 + tw/2; 0724 int sh = bh / 2 - th / 2; 0725 int eh = bh / 2 + th / 2; 0726 0727 unsigned int* tdata = reinterpret_cast<unsigned int*>(top.scanLine(0)); 0728 unsigned int* bdata = nullptr; 0729 0730 for (int y = sh ; y < eh ; ++y) 0731 { 0732 bdata = reinterpret_cast<unsigned int*>(bot.scanLine(y)) + sw; 0733 0734 for (int x = 0 ; x < tw ; ++x) 0735 { 0736 *(bdata++) = *(tdata++); 0737 } 0738 } 0739 } 0740 0741 void PresentationGL::printFilename(QImage& layer) 0742 { 0743 QFileInfo fileinfo(d->sharedData->urlList[d->fileIndex].toLocalFile()); 0744 QString filename = fileinfo.fileName(); 0745 QPixmap pix = generateOutlinedTextPixmap(filename); 0746 0747 // -------------------------------------------------------- 0748 0749 QPainter painter; 0750 painter.begin(&layer); 0751 painter.drawPixmap(d->xMargin, layer.height() - d->yMargin - pix.height(), pix); 0752 painter.end(); 0753 } 0754 0755 void PresentationGL::printProgress(QImage& layer) 0756 { 0757 QString progress(QString::number(d->fileIndex + 1) + QLatin1Char('/') + 0758 QString::number(d->sharedData->urlList.count())); 0759 0760 QPixmap pix = generateOutlinedTextPixmap(progress); 0761 0762 QPainter painter; 0763 painter.begin(&layer); 0764 painter.drawPixmap(layer.width() - d->xMargin - pix.width(), d->yMargin, pix); 0765 painter.end(); 0766 } 0767 0768 void PresentationGL::printComments(QImage& layer) 0769 { 0770 DItemInfo info(d->sharedData->iface->itemInfo(d->imageLoader->currPath())); 0771 QString comments = info.comment(); 0772 0773 int yPos = 5; // Text Y coordinate 0774 0775 if (d->sharedData->printFileName) 0776 { 0777 yPos += 20; 0778 } 0779 0780 QStringList commentsByLines; 0781 0782 uint commentsIndex = 0; // Comments QString index 0783 0784 while (commentsIndex < (uint) comments.length()) 0785 { 0786 QString newLine; 0787 bool breakLine = false; // End Of Line found 0788 uint currIndex; // Comments QString current index 0789 0790 // Check minimal lines dimension 0791 0792 int commentsLinesLengthLocal = d->sharedData->commentsLinesLength; 0793 0794 for (currIndex = commentsIndex ; (currIndex < (uint)comments.length()) && !breakLine ; ++currIndex) 0795 { 0796 if (comments[currIndex] == QLatin1Char('\n') || comments[currIndex].isSpace()) 0797 { 0798 breakLine = true; 0799 } 0800 } 0801 0802 if (commentsLinesLengthLocal <= (int)((currIndex - commentsIndex))) 0803 { 0804 commentsLinesLengthLocal = (currIndex - commentsIndex); 0805 } 0806 0807 breakLine = false; 0808 0809 for (currIndex = commentsIndex ; (currIndex <= (commentsIndex + commentsLinesLengthLocal)) && 0810 (currIndex < (uint)comments.length()) && !breakLine ; ++currIndex ) 0811 { 0812 breakLine = (comments[currIndex] == QLatin1Char('\n')) ? true : false; 0813 0814 if (breakLine) 0815 { 0816 newLine.append(QLatin1Char(' ')); 0817 } 0818 else 0819 { 0820 newLine.append(comments[currIndex]); 0821 } 0822 } 0823 0824 commentsIndex = currIndex; // The line is ended 0825 0826 if (commentsIndex != (uint) comments.length()) 0827 { 0828 while (!newLine.endsWith(QLatin1Char(' '))) 0829 { 0830 newLine.truncate(newLine.length() - 1); 0831 commentsIndex--; 0832 } 0833 } 0834 0835 commentsByLines.prepend(newLine.trimmed()); 0836 } 0837 0838 yPos += int(2.0 * d->sharedData->captionFont->pointSize()); 0839 0840 QFont font(*d->sharedData->captionFont); 0841 QColor fgColor(d->sharedData->commentsFontColor); 0842 QColor bgColor(d->sharedData->commentsBgColor); 0843 bool drawTextOutline = d->sharedData->commentsDrawOutline; 0844 int opacity = d->sharedData->bgOpacity; 0845 0846 for (int lineNumber = 0 ; lineNumber < (int)commentsByLines.count() ; ++lineNumber) 0847 { 0848 QPixmap pix = generateCustomOutlinedTextPixmap(commentsByLines[lineNumber], 0849 font, fgColor, bgColor, opacity, drawTextOutline); 0850 0851 QPainter painter; 0852 painter.begin(&layer); 0853 0854 int xPos = (layer.width() / 2) - (pix.width() / 2); 0855 painter.drawPixmap(xPos, layer.height() - pix.height() - yPos, pix); 0856 0857 painter.end(); 0858 0859 yPos += int(pix.height() + d->height / 400); 0860 } 0861 } 0862 0863 void PresentationGL::showEndOfShow() 0864 { 0865 QPixmap pix(width(), height()); 0866 pix.fill(Qt::black); 0867 0868 QFont fn(font()); 0869 fn.setPointSize(fn.pointSize() + 10); 0870 fn.setBold(true); 0871 0872 QPainter p(&pix); 0873 p.setPen(Qt::white); 0874 p.setFont(fn); 0875 p.drawText(20, 50, i18n("Slideshow Completed")); 0876 p.drawText(20, 100, i18n("Click to Exit...")); 0877 0878 // QPixmap logoPixmap = KPSvgPixmapRenderer(width() / 6, width() / 6).getPixmap(); 0879 // p.drawPixmap(width()-(width()/12)-logoPixmap.width(), 0880 // height()-(height()/12)-logoPixmap.height(), 0881 // logoPixmap); 0882 0883 p.end(); 0884 0885 QImage image(pix.toImage()); 0886 0887 /* create the texture */ 0888 0889 d->texture[2]->destroy(); 0890 d->texture[2]->setData(image.mirrored()); 0891 d->texture[2]->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); 0892 d->texture[2]->setMagnificationFilter(QOpenGLTexture::Linear); 0893 d->texture[2]->bind(); 0894 0895 /* paint the texture */ 0896 0897 glMatrixMode(GL_MODELVIEW); 0898 glLoadIdentity(); 0899 0900 glBegin(GL_QUADS); 0901 { 0902 glColor4f(1.0, 1.0, 1.0, 1.0); 0903 glTexCoord2f(0, 0); 0904 glVertex3f(-1.0, -1.0, 0); 0905 0906 glTexCoord2f(1, 0); 0907 glVertex3f(1.0, -1.0, 0); 0908 0909 glTexCoord2f(1, 1); 0910 glVertex3f(1.0, 1.0, 0); 0911 0912 glTexCoord2f(0, 1); 0913 glVertex3f(-1.0, 1.0, 0); 0914 } 0915 0916 glEnd(); 0917 } 0918 0919 void PresentationGL::showOverlays() 0920 { 0921 if (d->slideCtrlWidget->isHidden()) 0922 { 0923 int w = d->slideCtrlWidget->width() - 1; 0924 d->slideCtrlWidget->move(d->deskWidth - w, 0); 0925 d->slideCtrlWidget->show(); 0926 } 0927 0928 #ifdef HAVE_MEDIAPLAYER 0929 0930 if (d->playbackWidget->isHidden()) 0931 { 0932 d->playbackWidget->move(0, 0); 0933 d->playbackWidget->show(); 0934 } 0935 0936 #endif 0937 0938 } 0939 0940 void PresentationGL::hideOverlays() 0941 { 0942 d->slideCtrlWidget->hide(); 0943 0944 #ifdef HAVE_MEDIAPLAYER 0945 0946 d->playbackWidget->hide(); 0947 0948 #endif 0949 0950 } 0951 0952 void PresentationGL::slotTimeOut() 0953 { 0954 if (!d->effect) 0955 { 0956 qCWarning(DIGIKAM_DPLUGIN_GENERIC_LOG) << "PresentationGL: No transition method"; 0957 d->effect = &PresentationGL::effectNone; 0958 } 0959 0960 if (d->effectRunning) 0961 { 0962 d->timeout = 10; 0963 } 0964 else 0965 { 0966 if (d->timeout == 0) 0967 { 0968 // effect was running and is complete now 0969 // run timer while showing current image 0970 0971 d->timeout = d->sharedData->delay; 0972 d->i = 0; 0973 } 0974 else 0975 { 0976 0977 // timed out after showing current image 0978 // load next image and start effect 0979 0980 if (d->random) 0981 { 0982 d->effect = getRandomEffect(); 0983 } 0984 0985 if (d->sharedData->offAutoDelay) 0986 { 0987 d->effect = &PresentationGL::effectNone; 0988 d->timer->stop(); 0989 } 0990 0991 advanceFrame(); 0992 0993 if (d->endOfShow) 0994 { 0995 update(); 0996 return; 0997 } 0998 0999 loadImage(); 1000 1001 d->timeout = 10; 1002 d->effectRunning = true; 1003 d->i = 0; 1004 1005 } 1006 } 1007 1008 update(); 1009 1010 d->timer->start(d->timeout); 1011 1012 if (d->sharedData->offAutoDelay) 1013 { 1014 d->timer->stop(); 1015 } 1016 } 1017 1018 void PresentationGL::slotMouseMoveTimeOut() 1019 { 1020 QPoint pos(QCursor::pos()); 1021 1022 if ((pos.y() < 20) || 1023 (pos.y() > (d->deskHeight - 20 - 1)) || 1024 !d->timer->isActive() || 1025 d->slideCtrlWidget->underMouse() 1026 1027 #ifdef HAVE_MEDIAPLAYER 1028 1029 || d->playbackWidget->underMouse() 1030 1031 #endif 1032 1033 ) 1034 { 1035 return; 1036 } 1037 1038 setCursor(QCursor(Qt::BlankCursor)); 1039 } 1040 1041 void PresentationGL::paintTexture() 1042 { 1043 glMatrixMode(GL_MODELVIEW); 1044 glLoadIdentity(); 1045 GLuint tex = d->texture[d->curr]->textureId(); 1046 glBindTexture(GL_TEXTURE_2D, tex); 1047 1048 glBegin(GL_QUADS); 1049 { 1050 glColor4f(1.0, 1.0, 1.0, 1.0); 1051 glTexCoord2f(0, 0); 1052 glVertex3f(-1.0, -1.0, 0); 1053 1054 glTexCoord2f(1, 0); 1055 glVertex3f(1.0, -1.0, 0); 1056 1057 glTexCoord2f(1, 1); 1058 glVertex3f(1.0, 1.0, 0); 1059 1060 glTexCoord2f(0, 1); 1061 glVertex3f(-1.0, 1.0, 0); 1062 } 1063 1064 glEnd(); 1065 } 1066 1067 void PresentationGL::effectNone() 1068 { 1069 paintTexture(); 1070 d->effectRunning = false; 1071 d->timeout = 0; 1072 } 1073 1074 void PresentationGL::effectBlend() 1075 { 1076 if (d->i > 100) 1077 { 1078 paintTexture(); 1079 d->effectRunning = false; 1080 d->timeout = 0; 1081 return; 1082 } 1083 1084 int a = (d->curr == 0) ? 1 : 0; 1085 int b = d->curr; 1086 1087 GLuint ta = d->texture[a]->textureId(); 1088 GLuint tb = d->texture[b]->textureId(); 1089 1090 glBindTexture(GL_TEXTURE_2D, ta); 1091 1092 glBegin(GL_QUADS); 1093 { 1094 glColor4f(1.0, 1.0, 1.0, 1.0); 1095 glTexCoord2f(0, 0); 1096 glVertex3f(-1.0f, -1.0f, 0); 1097 1098 glTexCoord2f(1, 0); 1099 glVertex3f(1.0f, -1.0f, 0); 1100 1101 glTexCoord2f(1, 1); 1102 glVertex3f(1.0f, 1.0f, 0); 1103 1104 glTexCoord2f(0, 1); 1105 glVertex3f(-1.0f, 1.0f, 0); 1106 } 1107 1108 glEnd(); 1109 glBindTexture(GL_TEXTURE_2D, tb); 1110 1111 glBegin(GL_QUADS); 1112 { 1113 glColor4f(1.0, 1.0, 1.0, 1.0 / (100.0)*(float)d->i); 1114 glTexCoord2f(0, 0); 1115 glVertex3f(-1.0f, -1.0f, 0); 1116 1117 glTexCoord2f(1, 0); 1118 glVertex3f(1.0f, -1.0f, 0); 1119 1120 glTexCoord2f(1, 1); 1121 glVertex3f(1.0f, 1.0f, 0); 1122 1123 glTexCoord2f(0, 1); 1124 glVertex3f(-1.0f, 1.0f, 0); 1125 } 1126 1127 glEnd(); 1128 1129 d->i++; 1130 } 1131 1132 void PresentationGL::effectFade() 1133 { 1134 if (d->i > 100) 1135 { 1136 paintTexture(); 1137 d->effectRunning = false; 1138 d->timeout = 0; 1139 return; 1140 } 1141 1142 int a; 1143 float opacity; 1144 1145 if (d->i <= 50) 1146 { 1147 a = (d->curr == 0) ? 1 : 0; 1148 opacity = 1.0 - 1.0 / 50.0 * (float)(d->i); 1149 } 1150 else 1151 { 1152 opacity = 1.0 / 50.0 * (float)(d->i - 50.0); 1153 a = d->curr; 1154 } 1155 1156 GLuint ta = d->texture[a]->textureId(); 1157 glBindTexture(GL_TEXTURE_2D, ta); 1158 1159 glBegin(GL_QUADS); 1160 { 1161 glColor4f(1.0, 1.0, 1.0, opacity); 1162 glTexCoord2f(0, 0); 1163 glVertex3f(-1.0f, -1.0f, 0); 1164 1165 glTexCoord2f(1, 0); 1166 glVertex3f(1.0f, -1.0f, 0); 1167 1168 glTexCoord2f(1, 1); 1169 glVertex3f(1.0f, 1.0f, 0); 1170 1171 glTexCoord2f(0, 1); 1172 glVertex3f(-1.0f, 1.0f, 0); 1173 } 1174 1175 glEnd(); 1176 1177 d->i++; 1178 } 1179 1180 void PresentationGL::effectRotate() 1181 { 1182 if (d->i > 100) 1183 { 1184 paintTexture(); 1185 d->effectRunning = false; 1186 d->timeout = 0; 1187 return; 1188 } 1189 1190 if (d->i == 0) 1191 { 1192 d->dir = d->randomGenerator->bounded(2); 1193 } 1194 1195 int a = (d->curr == 0) ? 1 : 0; 1196 int b = d->curr; 1197 1198 GLuint ta = d->texture[a]->textureId(); 1199 GLuint tb = d->texture[b]->textureId(); 1200 glBindTexture(GL_TEXTURE_2D, tb); 1201 1202 glBegin(GL_QUADS); 1203 { 1204 glColor4f(1.0, 1.0, 1.0, 1.0); 1205 glTexCoord2f(0, 0); 1206 glVertex3f(-1.0f, -1.0f, 0); 1207 1208 glTexCoord2f(1, 0); 1209 glVertex3f(1.0f, -1.0f, 0); 1210 1211 glTexCoord2f(1, 1); 1212 glVertex3f(1.0f, 1.0f, 0); 1213 1214 glTexCoord2f(0, 1); 1215 glVertex3f(-1.0f, 1.0f, 0); 1216 } 1217 1218 glEnd(); 1219 1220 glMatrixMode(GL_MODELVIEW); 1221 glLoadIdentity(); 1222 float rotate = 360.0 / 100.0 * (float)d->i; 1223 glRotatef( ((d->dir == 0) ? -1 : 1) * rotate, 0.0, 0.0, 1.0); 1224 float scale = 1.0 / 100.0 * (100.0 - (float)(d->i)); 1225 glScalef(scale, scale, 1.0); 1226 glBindTexture(GL_TEXTURE_2D, ta); 1227 1228 glBegin(GL_QUADS); 1229 { 1230 glColor4f(1.0, 1.0, 1.0, 1.0); 1231 glTexCoord2f(0, 0); 1232 glVertex3f(-1.0f, -1.0f, 0); 1233 1234 glTexCoord2f(1, 0); 1235 glVertex3f(1.0f, -1.0f, 0); 1236 1237 glTexCoord2f(1, 1); 1238 glVertex3f(1.0f, 1.0f, 0); 1239 1240 glTexCoord2f(0, 1); 1241 glVertex3f(-1.0f, 1.0f, 0); 1242 } 1243 1244 glEnd(); 1245 1246 d->i++; 1247 } 1248 1249 void PresentationGL::effectBend() 1250 { 1251 if (d->i > 100) 1252 { 1253 paintTexture(); 1254 d->effectRunning = false; 1255 d->timeout = 0; 1256 return; 1257 } 1258 1259 if (d->i == 0) 1260 { 1261 d->dir = d->randomGenerator->bounded(2); 1262 } 1263 1264 int a = (d->curr == 0) ? 1 : 0; 1265 int b = d->curr; 1266 1267 GLuint ta = d->texture[a]->textureId(); 1268 GLuint tb = d->texture[b]->textureId(); 1269 glBindTexture(GL_TEXTURE_2D, tb); 1270 1271 glBegin(GL_QUADS); 1272 1273 { 1274 glColor4f(1.0, 1.0, 1.0, 1.0); 1275 glTexCoord2f(0, 0); 1276 glVertex3f(-1.0f, -1.0f, 0); 1277 1278 glTexCoord2f(1, 0); 1279 glVertex3f(1.0f, -1.0f, 0); 1280 1281 glTexCoord2f(1, 1); 1282 glVertex3f(1.0f, 1.0f, 0); 1283 1284 glTexCoord2f(0, 1); 1285 glVertex3f(-1.0f, 1.0f, 0); 1286 } 1287 1288 glEnd(); 1289 1290 glMatrixMode(GL_MODELVIEW); 1291 glLoadIdentity(); 1292 glRotatef(90.0 / 100.0*(float)d->i, 1293 (d->dir == 0) ? 1.0 : 0.0, 1294 (d->dir == 1) ? 1.0 : 0.0, 1295 0.0); 1296 1297 glBindTexture(GL_TEXTURE_2D, ta); 1298 1299 glBegin(GL_QUADS); 1300 { 1301 glColor4f(1.0, 1.0, 1.0, 1.0); 1302 glTexCoord2f(0, 0); 1303 glVertex3f(-1.0f, -1.0f, 0); 1304 1305 glTexCoord2f(1, 0); 1306 glVertex3f(1.0f, -1.0f, 0); 1307 1308 glTexCoord2f(1, 1); 1309 glVertex3f(1.0f, 1.0f, 0); 1310 1311 glTexCoord2f(0, 1); 1312 glVertex3f(-1.0f, 1.0f, 0); 1313 } 1314 1315 glEnd(); 1316 1317 d->i++; 1318 } 1319 1320 void PresentationGL::effectInOut() 1321 { 1322 if (d->i > 100) 1323 { 1324 paintTexture(); 1325 d->effectRunning = false; 1326 d->timeout = 0; 1327 return; 1328 } 1329 1330 if (d->i == 0) 1331 { 1332 d->dir = d->randomGenerator->bounded(1, 5); 1333 } 1334 1335 int a; 1336 bool out; 1337 1338 if (d->i <= 50) 1339 { 1340 a = (d->curr == 0) ? 1 : 0; 1341 out = 1; 1342 } 1343 else 1344 { 1345 a = d->curr; 1346 out = 0; 1347 } 1348 1349 GLuint ta = d->texture[a]->textureId(); 1350 glMatrixMode(GL_MODELVIEW); 1351 glLoadIdentity(); 1352 float t = out ? 1.0 / 50.0 * (50.0 - d->i) : 1.0 / 50.0 * (d->i - 50.0); 1353 glScalef(t, t, 1.0); 1354 t = 1.0 - t; 1355 glTranslatef((d->dir % 2 == 0) ? ((d->dir == 2) ? 1 : -1) * t : 0.0, 1356 (d->dir % 2 == 1) ? ((d->dir == 1) ? 1 : -1) * t : 0.0, 1357 0.0); 1358 1359 glBindTexture(GL_TEXTURE_2D, ta); 1360 1361 glBegin(GL_QUADS); 1362 { 1363 glColor4f(1.0, 1.0, 1.0, 1.0); 1364 1365 glColor4f(1.0, 1.0, 1.0, 1.0); 1366 glTexCoord2f(0, 0); 1367 glVertex3f(-1.0f, -1.0f, 0); 1368 1369 glTexCoord2f(1, 0); 1370 glVertex3f(1.0f, -1.0f, 0); 1371 1372 glTexCoord2f(1, 1); 1373 glVertex3f(1.0f, 1.0f, 0); 1374 1375 glTexCoord2f(0, 1); 1376 glVertex3f(-1.0f, 1.0f, 0); 1377 } 1378 1379 glEnd(); 1380 1381 d->i++; 1382 } 1383 1384 void PresentationGL::effectSlide() 1385 { 1386 if (d->i > 100) 1387 { 1388 paintTexture(); 1389 d->effectRunning = false; 1390 d->timeout = 0; 1391 return; 1392 } 1393 1394 if (d->i == 0) 1395 { 1396 d->dir = d->randomGenerator->bounded(1, 5); 1397 } 1398 1399 int a = (d->curr == 0) ? 1 : 0; 1400 int b = d->curr; 1401 GLuint ta = d->texture[a]->textureId(); 1402 GLuint tb = d->texture[b]->textureId(); 1403 glBindTexture(GL_TEXTURE_2D, tb); 1404 1405 glBegin(GL_QUADS); 1406 { 1407 glColor4f(1.0, 1.0, 1.0, 1.0); 1408 glTexCoord2f(0, 0); 1409 glVertex3f(-1.0f, -1.0f, 0); 1410 1411 glTexCoord2f(1, 0); 1412 glVertex3f(1.0f, -1.0f, 0); 1413 1414 glTexCoord2f(1, 1); 1415 glVertex3f(1.0f, 1.0f, 0); 1416 1417 glTexCoord2f(0, 1); 1418 glVertex3f(-1.0f, 1.0f, 0); 1419 } 1420 1421 glEnd(); 1422 1423 glMatrixMode(GL_MODELVIEW); 1424 glLoadIdentity(); 1425 float trans = 2.0 / 100.0 * (float)d->i; 1426 glTranslatef((d->dir % 2 == 0) ? ((d->dir == 2) ? 1 : -1) * trans : 0.0, 1427 (d->dir % 2 == 1) ? ((d->dir == 1) ? 1 : -1) * trans : 0.0, 1428 0.0); 1429 1430 glBindTexture(GL_TEXTURE_2D, ta); 1431 1432 glBegin(GL_QUADS); 1433 { 1434 glColor4f(1.0, 1.0, 1.0, 1.0); 1435 1436 glColor4f(1.0, 1.0, 1.0, 1.0); 1437 glTexCoord2f(0, 0); 1438 glVertex3f(-1.0f, -1.0f, 0); 1439 1440 glTexCoord2f(1, 0); 1441 glVertex3f(1.0f, -1.0f, 0); 1442 1443 glTexCoord2f(1, 1); 1444 glVertex3f(1.0f, 1.0f, 0); 1445 1446 glTexCoord2f(0, 1); 1447 glVertex3f(-1.0f, 1.0f, 0); 1448 } 1449 1450 glEnd(); 1451 1452 d->i++; 1453 } 1454 1455 void PresentationGL::effectFlutter() 1456 { 1457 if (d->i > 100) 1458 { 1459 paintTexture(); 1460 d->effectRunning = false; 1461 d->timeout = 0; 1462 return; 1463 } 1464 1465 int a = (d->curr == 0) ? 1 : 0; 1466 int b = d->curr; 1467 GLuint ta = d->texture[a]->textureId(); 1468 GLuint tb = d->texture[b]->textureId(); 1469 1470 if (d->i == 0) 1471 { 1472 for (int x = 0 ; x < 40 ; ++x) 1473 { 1474 for (int y = 0 ; y < 40 ; ++y) 1475 { 1476 d->points[x][y][0] = (float) (x / 20.0f - 1.0f); 1477 d->points[x][y][1] = (float) (y / 20.0f - 1.0f); 1478 d->points[x][y][2] = (float) sin((x / 20.0f - 1.0f) * 3.141592654 * 2.0f) / 5.0; 1479 } 1480 } 1481 } 1482 1483 glBindTexture(GL_TEXTURE_2D, tb); 1484 1485 glBegin(GL_QUADS); 1486 { 1487 glColor4f(1.0, 1.0, 1.0, 1.0); 1488 glTexCoord2f(0, 0); 1489 glVertex3f(-1.0f, -1.0f, 0); 1490 1491 glTexCoord2f(1, 0); 1492 glVertex3f(1.0f, -1.0f, 0); 1493 1494 glTexCoord2f(1, 1); 1495 glVertex3f(1.0f, 1.0f, 0); 1496 1497 glTexCoord2f(0, 1); 1498 glVertex3f(-1.0f, 1.0f, 0); 1499 } 1500 1501 glEnd(); 1502 1503 glMatrixMode(GL_MODELVIEW); 1504 glLoadIdentity(); 1505 float rotate = 60.0 / 100.0 * (float)d->i; 1506 glRotatef(rotate, 1.0f, 0.0f, 0.0f); 1507 float scale = 1.0 / 100.0 * (100.0 - (float)d->i); 1508 glScalef(scale, scale, scale); 1509 glTranslatef(1.0 / 100.0*(float)d->i, 1.0 / 100.0*(float)d->i, 0.0); 1510 glBindTexture(GL_TEXTURE_2D, ta); 1511 1512 glBegin(GL_QUADS); 1513 { 1514 glColor4f(1.0, 1.0, 1.0, 1.0); 1515 1516 float float_x, float_y, float_xb, float_yb; 1517 int x, y; 1518 1519 for (x = 0 ; x < 39 ; ++x) 1520 { 1521 for (y = 0 ; y < 39 ; ++y) 1522 { 1523 float_x = (float) x / 40.0f; 1524 float_y = (float) y / 40.0f; 1525 float_xb = (float) (x + 1) / 40.0f; 1526 float_yb = (float) (y + 1) / 40.0f; 1527 glTexCoord2f(float_x, float_y); 1528 glVertex3f(d->points[x][y][0], d->points[x][y][1], d->points[x][y][2]); 1529 glTexCoord2f(float_x, float_yb); 1530 glVertex3f(d->points[x][y + 1][0], d->points[x][y + 1][1], d->points[x][y + 1][2]); 1531 glTexCoord2f(float_xb, float_yb); 1532 glVertex3f(d->points[x + 1][y + 1][0], d->points[x + 1][y + 1][1], d->points[x + 1][y + 1][2]); 1533 glTexCoord2f(float_xb, float_y); 1534 glVertex3f(d->points[x + 1][y][0], d->points[x + 1][y][1], d->points[x + 1][y][2]); 1535 } 1536 } 1537 } 1538 1539 glEnd(); 1540 1541 // wave every two iterations 1542 1543 if ((d->i % 2) == 0) 1544 { 1545 1546 float hold; 1547 int x, y; 1548 1549 for (y = 0 ; y < 40 ; ++y) 1550 { 1551 hold = d->points[0][y][2]; 1552 1553 for (x = 0 ; x < 39 ; ++x) 1554 { 1555 d->points[x][y][2] = d->points[x + 1][y][2]; 1556 } 1557 1558 d->points[39][y][2] = hold; 1559 } 1560 } 1561 1562 d->i++; 1563 } 1564 1565 void PresentationGL::effectCube() 1566 { 1567 int tot = 200; 1568 int rotStart = 50; 1569 1570 if (d->i > tot) 1571 { 1572 paintTexture(); 1573 d->effectRunning = false; 1574 d->timeout = 0; 1575 return; 1576 } 1577 1578 // Enable perspective vision 1579 1580 glEnable(GL_DEPTH_TEST); 1581 glDepthFunc(GL_LEQUAL); 1582 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 1583 1584 int a = (d->curr == 0) ? 1 : 0; 1585 int b = d->curr; 1586 GLuint ta = d->texture[a]->textureId(); 1587 GLuint tb = d->texture[b]->textureId(); 1588 glMatrixMode(GL_PROJECTION); 1589 glLoadIdentity(); 1590 1591 // float PI = 4.0 * atan(1.0); 1592 float znear = 3.0; 1593 // float theta = 2.0 * atan2((float)2.0 / (float)2.0, (float)znear); 1594 // theta = theta * 180.0 / PI; 1595 1596 glFrustum(-1.0, 1.0, -1.0, 1.0, znear - 0.01, 10.0); 1597 1598 static float xrot; 1599 static float yrot; 1600 // static float zrot; 1601 1602 if (d->i == 0) 1603 { 1604 xrot = 0.0; 1605 yrot = 0.0; 1606 // zrot = 0.0; 1607 } 1608 1609 glMatrixMode( GL_MODELVIEW ); 1610 glLoadIdentity(); 1611 1612 float trans = 5.0 * (float)((d->i <= tot / 2) ? d->i : tot - d->i) / (float)tot; 1613 glTranslatef(0.0, 0.0, -znear - 1.0 - trans); 1614 1615 glRotatef(xrot, 1.0f, 0.0f, 0.0f); 1616 glRotatef(yrot, 0.0f, 1.0f, 0.0f); 1617 glBindTexture(GL_TEXTURE_2D, 0); 1618 1619 glBegin(GL_QUADS); 1620 { 1621 glColor4f(0.0f, 0.0f, 0.0f, 1.0f); 1622 1623 /* Front Face */ 1624 1625 glVertex3f( -1.00f, -1.00f, 0.99f ); 1626 glVertex3f( 1.00f, -1.00f, 0.99f ); 1627 glVertex3f( 1.00f, 1.00f, 0.99f ); 1628 glVertex3f( -1.00f, 1.00f, 0.99f ); 1629 1630 /* Back Face */ 1631 1632 glVertex3f( -1.00f, -1.00f, -0.99f ); 1633 glVertex3f( -1.00f, 1.00f, -0.99f ); 1634 glVertex3f( 1.00f, 1.00f, -0.99f ); 1635 glVertex3f( 1.00f, -1.00f, -0.99f ); 1636 1637 /* Top Face */ 1638 1639 glVertex3f( -1.00f, 0.99f, -1.00f ); 1640 glVertex3f( -1.00f, 0.99f, 1.00f ); 1641 glVertex3f( 1.00f, 0.99f, 1.00f ); 1642 glVertex3f( 1.00f, 0.99f, -1.00f ); 1643 1644 /* Bottom Face */ 1645 1646 glVertex3f( -1.00f, -0.99f, -1.00f ); 1647 glVertex3f( 1.00f, -0.99f, -1.00f ); 1648 glVertex3f( 1.00f, -0.99f, 1.00f ); 1649 glVertex3f( -1.00f, -0.99f, 1.00f ); 1650 1651 /* Right face */ 1652 1653 glVertex3f( 0.99f, -1.00f, -1.00f ); 1654 glVertex3f( 0.99f, 1.00f, -1.00f ); 1655 glVertex3f( 0.99f, 1.00f, 1.00f ); 1656 glVertex3f( 0.99f, -1.00f, 1.00f ); 1657 1658 /* Left Face */ 1659 1660 glVertex3f( -0.99f, -1.00f, -1.00f ); 1661 glVertex3f( -0.99f, -1.00f, 1.00f ); 1662 glVertex3f( -0.99f, 1.00f, 1.00f ); 1663 glVertex3f( -0.99f, 1.00f, -1.00f ); 1664 } 1665 1666 glEnd(); 1667 glBindTexture(GL_TEXTURE_2D, ta); 1668 1669 glBegin(GL_QUADS); 1670 { 1671 glColor4d(1.0, 1.0, 1.0, 1.0); 1672 1673 // Front Face 1674 1675 glTexCoord2f( 0.0f, 0.0f ); 1676 glVertex3f( -1.0f, -1.0f, 1.00f ); 1677 glTexCoord2f( 1.0f, 0.0f ); 1678 glVertex3f( 1.0f, -1.0f, 1.00f ); 1679 glTexCoord2f( 1.0f, 1.0f ); 1680 glVertex3f( 1.0f, 1.0f, 1.00f ); 1681 glTexCoord2f( 0.0f, 1.0f ); 1682 glVertex3f( -1.0f, 1.0f, 1.00f ); 1683 1684 // Top Face 1685 1686 glTexCoord2f( 1.0f, 1.0f ); 1687 glVertex3f( -1.0f, 1.00f, -1.0f ); 1688 glTexCoord2f( 1.0f, 0.0f ); 1689 glVertex3f( -1.0f, 1.00f, 1.0f ); 1690 glTexCoord2f( 0.0f, 0.0f ); 1691 glVertex3f( 1.0f, 1.00f, 1.0f ); 1692 glTexCoord2f( 0.0f, 1.0f ); 1693 glVertex3f( 1.0f, 1.00f, -1.0f ); 1694 1695 // Bottom Face 1696 1697 glTexCoord2f( 0.0f, 1.0f ); 1698 glVertex3f( -1.0f, -1.00f, -1.0f ); 1699 glTexCoord2f( 1.0f, 1.0f ); 1700 glVertex3f( 1.0f, -1.00f, -1.0f ); 1701 glTexCoord2f( 1.0f, 0.0f ); 1702 glVertex3f( 1.0f, -1.00f, 1.0f ); 1703 glTexCoord2f( 0.0f, 0.0f ); 1704 glVertex3f( -1.0f, -1.00f, 1.0f ); 1705 1706 // Right face 1707 1708 glTexCoord2f( 0.0f, 0.0f ); 1709 glVertex3f( 1.00f, -1.0f, -1.0f ); 1710 glTexCoord2f( 0.0f, 1.0f ); 1711 glVertex3f( 1.00f, -1.0f, 1.0f ); 1712 glTexCoord2f( 1.0f, 1.0f ); 1713 glVertex3f( 1.00f, 1.0f, 1.0f ); 1714 glTexCoord2f( 1.0f, 0.0f ); 1715 glVertex3f( 1.00f, 1.0f, -1.0f ); 1716 1717 // Left Face 1718 1719 glTexCoord2f( 1.0f, 0.0f ); 1720 glVertex3f( -1.00f, -1.0f, -1.0f ); 1721 glTexCoord2f( 0.0f, 0.0f ); 1722 glVertex3f( -1.00f, 1.0f, -1.0f ); 1723 glTexCoord2f( 0.0f, 1.0f ); 1724 glVertex3f( -1.00f, 1.0f, 1.0f ); 1725 glTexCoord2f( 1.0f, 1.0f ); 1726 glVertex3f( -1.00f, -1.0f, 1.0f ); 1727 } 1728 1729 glEnd(); 1730 glBindTexture(GL_TEXTURE_2D, tb); 1731 1732 glBegin(GL_QUADS); 1733 { 1734 glColor4d(1.0, 1.0, 1.0, 1.0); 1735 1736 // Back Face 1737 1738 glTexCoord2f( 1.0f, 0.0f ); 1739 glVertex3f( -1.0f, -1.0f, -1.00f ); 1740 glTexCoord2f( 1.0f, 1.0f ); 1741 glVertex3f( -1.0f, 1.0f, -1.00f ); 1742 glTexCoord2f( 0.0f, 1.0f ); 1743 glVertex3f( 1.0f, 1.0f, -1.00f ); 1744 glTexCoord2f( 0.0f, 0.0f ); 1745 glVertex3f( 1.0f, -1.0f, -1.00f ); 1746 } 1747 1748 glEnd(); 1749 1750 if ((d->i >= rotStart) && (d->i < (tot - rotStart))) 1751 { 1752 xrot += 360.0f / (float)(tot - 2 * rotStart); 1753 yrot += 180.0f / (float)(tot - 2 * rotStart); 1754 } 1755 1756 d->i++; 1757 } 1758 1759 void PresentationGL::slotPause() 1760 { 1761 d->timer->stop(); 1762 showOverlays(); 1763 } 1764 1765 void PresentationGL::slotPlay() 1766 { 1767 hideOverlays(); 1768 slotTimeOut(); 1769 } 1770 1771 void PresentationGL::slotPrev() 1772 { 1773 previousFrame(); 1774 1775 if (d->endOfShow) 1776 { 1777 update(); 1778 return; 1779 } 1780 1781 d->effectRunning = false; 1782 1783 loadImage(); 1784 update(); 1785 } 1786 1787 void PresentationGL::slotNext() 1788 { 1789 advanceFrame(); 1790 1791 if (d->endOfShow) 1792 { 1793 update(); 1794 return; 1795 } 1796 1797 d->effectRunning = false; 1798 1799 loadImage(); 1800 update(); 1801 } 1802 1803 void PresentationGL::slotClose() 1804 { 1805 close(); 1806 } 1807 1808 QPixmap PresentationGL::generateOutlinedTextPixmap(const QString& text) 1809 { 1810 QFont fn(font()); 1811 fn.setPointSize(fn.pointSize()); 1812 fn.setBold(true); 1813 1814 return generateOutlinedTextPixmap(text, fn); 1815 } 1816 1817 QPixmap PresentationGL::generateOutlinedTextPixmap(const QString& text, QFont& fn) 1818 { 1819 QColor fgColor(Qt::white); 1820 QColor bgColor(Qt::black); 1821 1822 return generateCustomOutlinedTextPixmap(text, fn, fgColor, bgColor, 0, true); 1823 } 1824 1825 QPixmap PresentationGL::generateCustomOutlinedTextPixmap(const QString& text, QFont& fn, 1826 QColor& fgColor, QColor& bgColor, 1827 int opacity, bool drawTextOutline) 1828 { 1829 QFontMetrics fm(fn); 1830 QRect rect = fm.boundingRect(text); 1831 rect.adjust( -fm.maxWidth(), -fm.height(), fm.maxWidth(), fm.height() / 2 ); 1832 1833 QPixmap pix(rect.width(), rect.height()); 1834 pix.fill(Qt::transparent); 1835 1836 if (opacity > 0) 1837 { 1838 QPainter pbg(&pix); 1839 pbg.setBrush(bgColor); 1840 pbg.setPen(bgColor); 1841 pbg.setOpacity(opacity / 10.0); 1842 pbg.drawRoundedRect(0, 0, 1843 (int)pix.width(), (int)pix.height(), 1844 (int)pix.height() / 3, (int)pix.height() / 3); 1845 } 1846 1847 QPainter p(&pix); 1848 p.setRenderHint(QPainter::Antialiasing, true); 1849 p.setBrush(QBrush()); 1850 p.setPen(QPen()); 1851 1852 // draw outline 1853 1854 QPainterPath path; 1855 path.addText(fm.maxWidth(), fm.height() * 1.5, fn, text); 1856 1857 QPainterPathStroker stroker; 1858 stroker.setWidth(2); 1859 stroker.setCapStyle(Qt::RoundCap); 1860 stroker.setJoinStyle(Qt::RoundJoin); 1861 QPainterPath outline = stroker.createStroke(path); 1862 1863 if (drawTextOutline) 1864 { 1865 p.fillPath(outline, Qt::black); 1866 } 1867 1868 p.fillPath(path, QBrush(fgColor)); 1869 1870 p.setRenderHint(QPainter::Antialiasing, false); 1871 p.end(); 1872 1873 return pix; 1874 } 1875 1876 bool PresentationGL::checkOpenGL() const 1877 { 1878 // No OpenGL context is found. Are the drivers ok? 1879 1880 if (!isValid()) 1881 { 1882 return false; 1883 } 1884 1885 // GL_EXT_texture3D is not supported 1886 1887 QString s = QString::fromLatin1(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 1888 1889 if (!s.contains(QString::fromLatin1("GL_EXT_texture3D"), Qt::CaseInsensitive)) 1890 { 1891 return false; 1892 } 1893 1894 // Everything is ok! 1895 1896 return true; 1897 } 1898 1899 } // namespace DigikamGenericPresentationPlugin 1900 1901 #include "moc_presentationgl.cpp"