00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "glsingleview.h"
00024
00025
00026 #include <cmath>
00027
00028
00029 #include <algorithm>
00030 using namespace std;
00031
00032
00033 #include <QTimer>
00034 #include <QImage>
00035 #include <QDir>
00036 #include <QPainter>
00037 #include <qbuffer.h>
00038
00039
00040 #include <mythcontext.h>
00041 #include <mythmiscutil.h>
00042 #include <mythuihelper.h>
00043 #include "mythlogging.h"
00044
00045
00046 #include "galleryutil.h"
00047
00048 #define LOC QString("GLView: ")
00049
00050 GLSDialog::GLSDialog(const ThumbList& itemList,
00051 int *pos, int slideShow, int sortOrder,
00052 MythMainWindow *parent, const char *name)
00053 : MythDialog(parent, name)
00054 {
00055 QBoxLayout *l = new QVBoxLayout(this);
00056 l->setContentsMargins(0, 0, 0, 0);
00057 m_view = new GLSingleView(itemList, pos, slideShow, sortOrder, this);
00058 l->addWidget(m_view);
00059
00060 setFocusProxy(m_view);
00061 m_view->setFocus();
00062 }
00063
00064
00065
00066
00067 void GLSDialog::closeEvent(QCloseEvent *e)
00068 {
00069 m_view->CleanUp();
00070 e->accept();
00071
00072 accept();
00073 }
00074
00075 GLSingleView::GLSingleView(ThumbList itemList, int *pos, int slideShow,
00076 int sortorder, QWidget *parent)
00077 : QGLWidget(parent),
00078 ImageView(itemList, pos, slideShow, sortorder),
00079
00080 m_source_x(0.0f),
00081 m_source_y(0.0f),
00082 m_scaleMax(kScaleToFit),
00083
00084
00085 m_texMaxDim(512),
00086 m_texSize(512,512),
00087 m_texCur(0),
00088 m_tex1First(true),
00089
00090
00091 m_texInfo(0),
00092
00093
00094 m_effect_rotate_direction(0),
00095 m_effect_transition_timeout(2000),
00096 m_effect_transition_timeout_inv(1.0f / m_effect_transition_timeout),
00097
00098
00099 m_effect_cube_xrot(0.0f),
00100 m_effect_cube_yrot(0.0f),
00101 m_effect_cube_zrot(0.0f),
00102 m_effect_kenBurns_image_ready(true),
00103 m_effect_kenBurns_initialized(false),
00104 m_effect_kenBurns_new_image_started(true)
00105 {
00106 m_scaleMax = (ScaleMax) gCoreContext->GetNumSetting("GalleryScaleMax", 0);
00107
00108 m_slideshow_timer = new QTimer(this);
00109 RegisterEffects();
00110
00111
00112
00113 setFocusPolicy(Qt::WheelFocus);
00114
00115
00116
00117 QString transType = gCoreContext->GetSetting("SlideshowOpenGLTransition");
00118 if (!transType.isEmpty() && m_effect_map.contains(transType))
00119 m_effect_method = m_effect_map[transType];
00120
00121 if (m_effect_method.isEmpty() || transType == QString("random (gl)"))
00122 {
00123 m_effect_method = GetRandomEffect();
00124 m_effect_random = true;
00125 }
00126
00127 SetTransitionTimeout(gCoreContext->GetNumSetting(
00128 "SlideshowOpenGLTransitionLength", 2000));
00129
00130
00131
00132 connect(m_slideshow_timer, SIGNAL(timeout()), this, SLOT(SlideTimeout()));
00133
00134
00135
00136 if (slideShow)
00137 {
00138 m_slideshow_running = true;
00139 m_slideshow_timer->stop();
00140 m_slideshow_timer->setSingleShot(true);
00141 m_slideshow_timer->start(m_slideshow_frame_delay_state);
00142 GetMythUI()->DisableScreensaver();
00143 }
00144 }
00145
00146 GLSingleView::~GLSingleView()
00147 {
00148
00149 gCoreContext->SaveSetting("GalleryScaleMax", m_scaleMax);
00150 CleanUp();
00151 }
00152
00153 void GLSingleView::CleanUp(void)
00154 {
00155 makeCurrent();
00156
00157 if (m_slideshow_timer)
00158 {
00159 m_slideshow_timer->stop();
00160 m_slideshow_timer->deleteLater();
00161 m_slideshow_timer = NULL;
00162 }
00163
00164 m_texItem[0].Deinit();
00165 m_texItem[1].Deinit();
00166
00167 if (m_texInfo)
00168 glDeleteTextures(1, &m_texInfo);
00169 }
00170
00171 void GLSingleView::initializeGL(void)
00172 {
00173
00174 glEnable(GL_TEXTURE_2D);
00175
00176 glClearColor(0.0, 0.0, 0.0, 1.0f);
00177
00178
00179 glEnable(GL_BLEND);
00180
00181 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00182
00183
00184 glClearDepth(1.0f);
00185
00186 GLint param;
00187 glGetIntegerv(GL_MAX_TEXTURE_SIZE, ¶m);
00188 m_texMaxDim = param;
00189
00190 Load();
00191 }
00192
00193 void GLSingleView::resizeGL(int w, int h)
00194 {
00195
00196 glViewport(0, 0, (GLint)w, (GLint)h);
00197
00198 glMatrixMode(GL_PROJECTION);
00199 glLoadIdentity();
00200 }
00201
00202 void GLSingleView::paintGL(void)
00203 {
00204 if (1 == m_movieState)
00205 {
00206 m_movieState = 2;
00207
00208 ThumbItem *item = m_itemList.at(m_pos);
00209
00210 if (item)
00211 GalleryUtil::PlayVideo(item->GetPath());
00212
00213 if (!m_slideshow_running && item)
00214 {
00215 QImage image;
00216 GetScreenShot(image, item);
00217 if (image.isNull())
00218 return;
00219
00220 image = image.scaled(800, 600);
00221
00222
00223 QPainter p(&image);
00224 QRect rect = QRect(20, image.height() - 100,
00225 image.width() - 40, 80);
00226 p.fillRect(rect, QBrush(QColor(0,0,0,100)));
00227 p.setFont(QFont("Arial", 25, QFont::Bold));
00228 p.setPen(QColor(255,255,255));
00229 p.drawText(rect, Qt::AlignCenter, tr("Press SELECT to play again"));
00230 p.end();
00231
00232 m_texSize = QSize(
00233 GetNearestGLTextureSize(image.size().width()),
00234 GetNearestGLTextureSize(image.size().height()));
00235 int a = m_tex1First ? 0 : 1;
00236 m_texItem[a].SetItem(item, image.size());
00237 m_texItem[a].ScaleTo(m_screenSize, m_scaleMax);
00238 m_texItem[a].Init(convertToGLFormat(
00239 image.scaled(m_texSize,
00240 Qt::IgnoreAspectRatio,
00241 Qt::SmoothTransformation)));
00242 }
00243 }
00244
00245 glDisable(GL_DEPTH_TEST);
00246
00247 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00248 glLoadIdentity();
00249
00250 glMatrixMode(GL_PROJECTION);
00251 glLoadIdentity();
00252
00253 glMatrixMode(GL_MODELVIEW);
00254 glLoadIdentity();
00255
00256 if (m_effect_running && !m_effect_method.isEmpty())
00257 {
00258 RunEffect(m_effect_method);
00259 }
00260 else
00261 {
00262 paintTexture();
00263 }
00264
00265 if (glGetError())
00266 LOG(VB_GENERAL, LOG_ERR, LOC + "OpenGL error detected");
00267 }
00268
00269 void GLSingleView::keyPressEvent(QKeyEvent *e)
00270 {
00271 bool handled = false;
00272
00273 bool wasRunning = m_slideshow_running;
00274 m_slideshow_timer->stop();
00275 m_slideshow_running = false;
00276 GetMythUI()->RestoreScreensaver();
00277 m_effect_running = false;
00278 m_slideshow_frame_delay_state = m_slideshow_frame_delay * 1000;
00279
00280 bool wasInfo = m_info_show;
00281 m_info_show = false;
00282 bool wasInfoShort = m_info_show_short;
00283 m_info_show_short = false;
00284
00285 QStringList actions;
00286 handled = GetMythMainWindow()->TranslateKeyPress("Gallery", e, actions);
00287
00288 float scrollX = 0.2f;
00289 float scrollY = 0.2f;
00290
00291 for (int i = 0; i < actions.size() && !handled; i++)
00292 {
00293 QString action = actions[i];
00294 handled = true;
00295
00296 if (action == "LEFT" || action == "UP")
00297 {
00298 m_info_show = wasInfo;
00299 m_slideshow_running = wasRunning;
00300 DisplayPrev(true, true);
00301 }
00302 else if (action == "RIGHT" || action == "DOWN")
00303 {
00304 m_info_show = wasInfo;
00305 m_slideshow_running = wasRunning;
00306 DisplayNext(true, true);
00307 }
00308 else if (action == "ZOOMOUT")
00309 {
00310 if (m_zoom > 0.5f)
00311 {
00312 SetZoom(m_zoom - 0.5f);
00313 if (m_zoom > 1.0f)
00314 {
00315 m_source_x -= m_source_x / ((m_zoom + 0.5) * 2.0f);
00316 m_source_y -= m_source_y / ((m_zoom + 0.5) * 2.0f);
00317
00318 checkPosition();
00319 }
00320 else
00321 {
00322 m_source_x = 0;
00323 m_source_y = 0;
00324 }
00325 }
00326 }
00327 else if (action == "ZOOMIN")
00328 {
00329 if (m_zoom < 4.0f)
00330 {
00331 SetZoom(m_zoom + 0.5f);
00332 if (m_zoom > 1.0f)
00333 {
00334 m_source_x += m_source_x / (m_zoom * 2.0f);
00335 m_source_y += m_source_y / (m_zoom * 2.0f);
00336
00337 checkPosition();
00338 }
00339 else
00340 {
00341 m_source_x = 0;
00342 m_source_y = 0;
00343 }
00344 }
00345 }
00346 else if (action == "FULLSIZE")
00347 {
00348 m_source_x = 0;
00349 m_source_y = 0;
00350 if (m_zoom != 1)
00351 SetZoom(1.0f);
00352 }
00353 else if (action == "SCROLLLEFT")
00354 {
00355 if (m_zoom > 1.0f && m_source_x < m_zoom - 1.0f)
00356 {
00357 m_source_x += scrollX;
00358 m_source_x = min(m_source_x, m_zoom - 1.0f);
00359 }
00360 }
00361 else if (action == "SCROLLRIGHT")
00362 {
00363 if (m_zoom > 1.0f && m_source_x > -m_zoom + 1.0f)
00364 {
00365 m_source_x -= scrollX;
00366 m_source_x = max(m_source_x, -m_zoom + 1.0f);
00367 }
00368 }
00369 else if (action == "SCROLLDOWN")
00370 {
00371 if (m_zoom > 1.0f && m_source_y < m_zoom - 1.0f)
00372 {
00373 m_source_y += scrollY;
00374 m_source_y = min(m_source_y, m_zoom - 1.0f);
00375 }
00376 }
00377 else if (action == "SCROLLUP")
00378 {
00379 if (m_zoom > 1.0f && m_source_y > -m_zoom + 1.0f)
00380 {
00381 m_source_y -= scrollY;
00382 m_source_y = max(m_source_y, -m_zoom + 1.0f);
00383 }
00384 }
00385 else if (action == "RECENTER")
00386 {
00387 if (m_zoom > 1.0f)
00388 {
00389 m_source_x = 0.0f;
00390 m_source_y = 0.0f;
00391 }
00392 }
00393 else if (action == "UPLEFT")
00394 {
00395 if (m_zoom > 1.0f)
00396 {
00397 m_source_x = 1.0f;
00398 m_source_y = -1.0f;
00399 }
00400 }
00401 else if (action == "LOWRIGHT")
00402 {
00403 if (m_zoom > 1.0f)
00404 {
00405 m_source_x = -1.0f;
00406 m_source_y = 1.0f;
00407 }
00408 }
00409 else if (action == "ROTRIGHT")
00410 {
00411 m_source_x = 0;
00412 m_source_y = 0;
00413 Rotate(90);
00414 }
00415 else if (action == "ROTLEFT")
00416 {
00417 m_source_x = 0;
00418 m_source_y = 0;
00419 Rotate(-90);
00420 }
00421 else if (action == "DELETE")
00422 {
00423 ThumbItem *item = m_itemList.at(m_pos);
00424 if (item && GalleryUtil::Delete(item->GetPath()))
00425 {
00426 item->SetPixmap(NULL);
00427 DisplayNext(true, true);
00428 }
00429 m_info_show = wasInfo;
00430 m_slideshow_running = wasRunning;
00431 }
00432 else if ((action == "PLAY" || action == "SELECT") && m_movieState == 2)
00433 {
00434 m_movieState = 1;
00435 }
00436 else if (action == "PLAY" || action == "SLIDESHOW" ||
00437 action == "RANDOMSHOW")
00438 {
00439 m_source_x = 0;
00440 m_source_y = 0;
00441 SetZoom(1.0f);
00442 m_info_show = wasInfo;
00443 m_info_show_short = true;
00444 m_slideshow_running = !wasRunning;
00445 }
00446 else if (action == "INFO")
00447 {
00448 m_info_show = !wasInfo && !wasInfoShort;
00449 m_slideshow_running = wasRunning;
00450 }
00451 else if (action == "FULLSCREEN")
00452 {
00453 m_scaleMax = (ScaleMax) ((m_scaleMax + 1) % kScaleMaxCount);
00454 m_source_x = 0;
00455 m_source_y = 0;
00456 SetZoom(1.0f);
00457
00458 int a = m_tex1First ? 0 : 1;
00459 m_texItem[a].ScaleTo(m_screenSize, m_scaleMax);
00460 }
00461 else
00462 {
00463 handled = false;
00464 }
00465 }
00466
00467 if (m_slideshow_running || m_info_show_short)
00468 {
00469 m_slideshow_timer->stop();
00470 m_slideshow_timer->setSingleShot(true);
00471 m_slideshow_timer->start(m_slideshow_frame_delay_state);
00472 }
00473
00474 if (m_slideshow_running)
00475 {
00476 GetMythUI()->DisableScreensaver();
00477 }
00478
00479 updateGL();
00480
00481 if (handled)
00482 {
00483 e->accept();
00484 }
00485 else {
00486 e->ignore();
00487 }
00488 }
00489
00490 void GLSingleView::checkPosition(void)
00491 {
00492 m_source_x = max(m_source_x, -m_zoom + 1.0f);
00493 m_source_y = max(m_source_y, -m_zoom + 1.0f);
00494 m_source_x = min(m_source_x, m_zoom - 1.0f);
00495 m_source_y = min(m_source_y, m_zoom - 1.0f);
00496 }
00497
00498 void GLSingleView::paintTexture(void)
00499 {
00500 glMatrixMode(GL_MODELVIEW);
00501 glLoadIdentity();
00502
00503 glTranslatef(m_source_x, m_source_y, 0.0f);
00504 glScalef(m_zoom, m_zoom, 1.0f);
00505
00506 m_texItem[m_texCur].MakeQuad();
00507
00508 if (m_info_show || m_info_show_short)
00509 {
00510 createTexInfo();
00511
00512 glMatrixMode(GL_MODELVIEW);
00513 glLoadIdentity();
00514
00515 glMatrixMode(GL_TEXTURE);
00516 glLoadIdentity();
00517
00518 glBindTexture(GL_TEXTURE_2D, m_texInfo);
00519 glBegin(GL_QUADS);
00520 {
00521 glColor4f(1.0f, 1.0f, 1.0f, 0.72f);
00522 glTexCoord2f(0.0f, 0.0f);
00523 glVertex3f(-0.75f, -0.75f, 0.0f);
00524
00525 glTexCoord2f(1.0f, 0.0f);
00526 glVertex3f(+0.75f, -0.75f, 0.0f);
00527
00528 glTexCoord2f(1.0f, 1.0f);
00529 glVertex3f(+0.75f, +0.75f, 0.0f);
00530
00531 glTexCoord2f(0.0f, 1.0f);
00532 glVertex3f(-0.75f, +0.75f, 0.0f);
00533 }
00534 glEnd();
00535 }
00536 }
00537
00538 void GLSingleView::DisplayNext(bool reset, bool loadImage)
00539 {
00540 if (reset)
00541 {
00542 m_zoom = 1.0f;
00543 m_source_x = 0.0f;
00544 m_source_y = 0.0f;
00545 }
00546
00547
00548
00549 ThumbItem *item;
00550 int oldpos = m_pos;
00551
00552 while (true)
00553 {
00554 m_pos = m_slideshow_sequence->next();
00555 item = m_itemList.at(m_pos);
00556 if (item)
00557 {
00558 if (QFile::exists(item->GetPath()))
00559 {
00560 break;
00561 }
00562 }
00563 if (m_pos == oldpos)
00564 {
00565
00566 close();
00567 }
00568 }
00569
00570 m_tex1First = !m_tex1First;
00571 m_texCur = (m_texCur) ? 0 : 1;
00572
00573 if (loadImage)
00574 Load();
00575 }
00576
00577 void GLSingleView::DisplayPrev(bool reset, bool loadImage)
00578 {
00579 if (reset)
00580 {
00581 m_zoom = 1.0f;
00582 m_source_x = 0.0f;
00583 m_source_y = 0.0f;
00584 }
00585
00586
00587
00588 int oldpos = m_pos;
00589 while (true)
00590 {
00591 m_pos = m_slideshow_sequence->prev();
00592
00593 ThumbItem *item = m_itemList.at(m_pos);
00594 if (item && QFile::exists(item->GetPath()))
00595 break;
00596
00597 if (m_pos == oldpos)
00598 {
00599
00600 close();
00601 }
00602 };
00603
00604 m_tex1First = !m_tex1First;
00605 m_texCur = (m_texCur) ? 0 : 1;
00606
00607 if (loadImage)
00608 Load();
00609 }
00610
00611 void GLSingleView::Load(void)
00612 {
00613 m_movieState = 0;
00614 ThumbItem *item = m_itemList.at(m_pos);
00615 if (!item)
00616 {
00617 LOG(VB_GENERAL, LOG_ERR, LOC + QString("No item at %1").arg(m_pos));
00618 return;
00619 }
00620
00621 if (GalleryUtil::IsMovie(item->GetPath()))
00622 {
00623 m_movieState = 1;
00624 return;
00625 }
00626
00627 QImage image(item->GetPath());
00628 if (image.isNull())
00629 return;
00630
00631 m_texSize = QSize(GetNearestGLTextureSize(image.size().width()),
00632 GetNearestGLTextureSize(image.size().height()));
00633 int a = m_tex1First ? 0 : 1;
00634 m_texItem[a].SetItem(item, image.size());
00635 m_texItem[a].ScaleTo(m_screenSize, m_scaleMax);
00636 m_texItem[a].Init(convertToGLFormat(
00637 image.scaled(m_texSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)));
00638
00639 UpdateLCD(item);
00640 }
00641
00642 void GLSingleView::Rotate(int angle)
00643 {
00644 int ang = m_texItem[m_texCur].GetAngle() + angle;
00645
00646 ang = (ang >= 360) ? ang - 360 : ang;
00647 ang = (ang < 0) ? ang + 360 : ang;
00648
00649 m_texItem[m_texCur].SetAngle(ang);
00650
00651 ThumbItem *item = m_itemList.at(m_pos);
00652 if (item)
00653 item->SetRotationAngle(ang);
00654
00655 m_texItem[m_texCur].SwapWidthHeight();
00656 m_texItem[m_texCur].ScaleTo(m_screenSize, m_scaleMax);
00657 }
00658
00659 void GLSingleView::SetZoom(float zoom)
00660 {
00661 m_zoom = zoom;
00662 }
00663
00664 void GLSingleView::SetTransitionTimeout(int timeout)
00665 {
00666 m_effect_transition_timeout = timeout;
00667 m_effect_transition_timeout_inv = 1.0f;
00668 if (timeout)
00669 m_effect_transition_timeout_inv = 1.0f / timeout;
00670 }
00671
00672 int GLSingleView::GetNearestGLTextureSize(int v) const
00673 {
00674 int n = 0, last = 0;
00675 int s;
00676
00677 for (s = 0; s < 32; ++s)
00678 {
00679 if (((v >> s) & 1) == 1)
00680 {
00681 ++n;
00682 last = s;
00683 }
00684 }
00685
00686 if (n > 1)
00687 s = 1 << (last + 1);
00688 else
00689 s = 1 << last;
00690
00691 return min(s, m_texMaxDim);
00692 }
00693
00694 void GLSingleView::RegisterEffects(void)
00695 {
00696 m_effect_map.insert("none", "EffectNone");
00697 m_effect_map.insert("blend (gl)", "EffectBlend");
00698 m_effect_map.insert("zoom blend (gl)", "EffectZoomBlend");
00699 m_effect_map.insert("fade (gl)", "EffectFade");
00700 m_effect_map.insert("rotate (gl)", "EffectRotate");
00701 m_effect_map.insert("bend (gl)", "EffectBend");
00702 m_effect_map.insert("inout (gl)", "EffectInOut");
00703 m_effect_map.insert("slide (gl)", "EffectSlide");
00704 m_effect_map.insert("flutter (gl)", "EffectFlutter");
00705 m_effect_map.insert("cube (gl)", "EffectCube");
00706 m_effect_map.insert("Ken Burns (gl)", "EffectKenBurns");
00707 }
00708
00709 void GLSingleView::RunEffect(const QString &effect)
00710 {
00711 if (effect == "EffectBlend")
00712 EffectBlend();
00713 else if (effect == "EffectZoomBlend")
00714 EffectZoomBlend();
00715 else if (effect == "EffectFade")
00716 EffectFade();
00717 else if (effect == "EffectRotate")
00718 EffectRotate();
00719 else if (effect == "EffectBend")
00720 EffectBend();
00721 else if (effect == "EffectInOut")
00722 EffectInOut();
00723 else if (effect == "EffectSlide")
00724 EffectSlide();
00725 else if (effect == "EffectFlutter")
00726 EffectFlutter();
00727 else if (effect == "EffectCube")
00728 EffectCube();
00729 else if (effect == "EffectKenBurns")
00730 EffectKenBurns();
00731 else
00732 EffectNone();
00733 }
00734
00735 void GLSingleView::EffectNone(void)
00736 {
00737 paintTexture();
00738 m_effect_running = false;
00739 m_slideshow_frame_delay_state = -1;
00740 return;
00741 }
00742
00743 void GLSingleView::EffectBlend(void)
00744 {
00745 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00746 {
00747 paintTexture();
00748 m_effect_running = false;
00749 m_slideshow_frame_delay_state = -1;
00750 return;
00751 }
00752
00753 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00754
00755 m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
00756
00757 glBegin(GL_QUADS);
00758 {
00759 glColor4f(0.0f, 0.0f, 0.0f, 1.0f * t);
00760 glVertex3f(-1.0f, -1.0f, 0.0f);
00761 glVertex3f(+1.0f, -1.0f, 0.0f);
00762 glVertex3f(+1.0f, +1.0f, 0.0f);
00763 glVertex3f(-1.0f, +1.0f, 0.0f);
00764 }
00765 glEnd();
00766
00767 m_texItem[m_texCur].MakeQuad(t);
00768
00769 m_effect_current_frame++;
00770 }
00771
00772 void GLSingleView::EffectZoomBlend(void)
00773 {
00774 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00775 {
00776 paintTexture();
00777 m_effect_running = false;
00778 m_slideshow_frame_delay_state = -1;
00779 return;
00780 }
00781
00782 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00783
00784 m_texItem[m_texCur ? 0 : 1].MakeQuad(1.0f - t, 1.0f + (0.75 * t));
00785 m_texItem[m_texCur].MakeQuad(t);
00786
00787 m_effect_current_frame++;
00788 }
00789
00790 void GLSingleView::EffectRotate(void)
00791 {
00792 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00793 {
00794 paintTexture();
00795 m_effect_running = false;
00796 m_slideshow_frame_delay_state = -1;
00797 return;
00798 }
00799
00800 if (m_effect_current_frame == 0)
00801 m_effect_rotate_direction = (int)((2.0*random()/(RAND_MAX+1.0)));
00802
00803 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00804
00805 m_texItem[m_texCur].MakeQuad();
00806
00807 glMatrixMode(GL_MODELVIEW);
00808 glLoadIdentity();
00809 float rotate = 360.0f * t;
00810 glRotatef(((m_effect_rotate_direction == 0) ? -1 : 1) * rotate,
00811 0.0f, 0.0f, 1.0f);
00812 float scale = 1.0f * (1.0f - t);
00813 glScalef(scale, scale, 1.0f);
00814
00815 m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
00816
00817 m_effect_current_frame++;
00818 }
00819
00820 void GLSingleView::EffectBend(void)
00821 {
00822 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00823 {
00824 paintTexture();
00825 m_effect_running = false;
00826 m_slideshow_frame_delay_state = -1;
00827 return;
00828 }
00829
00830 if (m_effect_current_frame == 0)
00831 m_effect_rotate_direction = (int)((2.0f*random()/(RAND_MAX+1.0f)));
00832
00833 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00834
00835 m_texItem[m_texCur].MakeQuad();
00836
00837 glMatrixMode(GL_MODELVIEW);
00838 glLoadIdentity();
00839 glRotatef(90.0f * t,
00840 (m_effect_rotate_direction == 0) ? 1.0f : 0.0f,
00841 (m_effect_rotate_direction == 1) ? 1.0f : 0.0f,
00842 0.0f);
00843
00844 m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
00845
00846 m_effect_current_frame++;
00847 }
00848
00849 void GLSingleView::EffectFade(void)
00850 {
00851 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00852 {
00853 paintTexture();
00854 m_effect_running = false;
00855 m_slideshow_frame_delay_state = -1;
00856 return;
00857 }
00858
00859 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00860
00861 if (m_effect_frame_time.elapsed() <= m_effect_transition_timeout / 2)
00862 m_texItem[(m_texCur) ? 0 : 1].MakeQuad(1.0f - (2.0f * t));
00863 else
00864 m_texItem[m_texCur].MakeQuad(2.0f * (t - 0.5f));
00865
00866 m_effect_current_frame++;
00867 }
00868
00869 void GLSingleView::EffectInOut(void)
00870 {
00871 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00872 {
00873 paintTexture();
00874 m_effect_running = false;
00875 m_slideshow_frame_delay_state = -1;
00876 return;
00877 }
00878
00879 if (m_effect_current_frame == 0)
00880 {
00881 m_effect_rotate_direction = 1 + (int)((4.0f*random()/(RAND_MAX+1.0f)));
00882 }
00883
00884 int texnum = m_texCur;
00885 bool fadeout = false;
00886 if (m_effect_frame_time.elapsed() <= m_effect_transition_timeout / 2)
00887 {
00888 texnum = (m_texCur) ? 0 : 1;
00889 fadeout = true;
00890 }
00891
00892 glMatrixMode(GL_MODELVIEW);
00893 glLoadIdentity();
00894
00895 float tt = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00896 float t = 2.0f / ((fadeout) ? (0.5f - tt) : (tt - 0.5f));
00897
00898 glScalef(t, t, 1.0f);
00899 t = 1.0f - t;
00900 glTranslatef((m_effect_rotate_direction % 2 == 0) ? ((m_effect_rotate_direction == 2)? 1 : -1) * t : 0.0f,
00901 (m_effect_rotate_direction % 2 == 1) ? ((m_effect_rotate_direction == 1)? 1 : -1) * t : 0.0f,
00902 0.0f);
00903
00904 m_texItem[texnum].MakeQuad();
00905
00906 m_effect_current_frame++;
00907 }
00908
00909 void GLSingleView::EffectSlide(void)
00910 {
00911 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00912 {
00913 paintTexture();
00914 m_effect_running = false;
00915 m_slideshow_frame_delay_state = -1;
00916 return;
00917 }
00918
00919 if (m_effect_current_frame == 0)
00920 m_effect_rotate_direction = 1 + (int)((4.0f * random() / (RAND_MAX + 1.0f)));
00921
00922 m_texItem[m_texCur].MakeQuad();
00923
00924 glMatrixMode(GL_MODELVIEW);
00925 glLoadIdentity();
00926 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00927 float trans = 2.0f * t;
00928 glTranslatef((m_effect_rotate_direction % 2 == 0) ? ((m_effect_rotate_direction == 2)? 1 : -1) * trans : 0.0f,
00929 (m_effect_rotate_direction % 2 == 1) ? ((m_effect_rotate_direction == 1)? 1 : -1) * trans : 0.0f,
00930 0.0f);
00931
00932 m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
00933
00934 m_effect_current_frame++;
00935 }
00936
00937 void GLSingleView::EffectFlutter(void)
00938 {
00939 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00940 {
00941 paintTexture();
00942 m_effect_running = false;
00943 m_slideshow_frame_delay_state = -1;
00944 return;
00945 }
00946
00947 GLTexture &ta = m_texItem[(m_texCur) ? 0 : 1];
00948
00949 if (m_effect_current_frame == 0)
00950 {
00951 for (int x = 0; x < 40; x++)
00952 {
00953 for (int y = 0; y < 40; y++)
00954 {
00955 m_effect_flutter_points[x][y][0] =
00956 (float) (x / 20.0f - 1.0f) * ta.GetTextureX();
00957 m_effect_flutter_points[x][y][1] =
00958 (float) (y / 20.0f - 1.0f) * ta.GetTextureY();
00959 m_effect_flutter_points[x][y][2] =
00960 (float) sin((x / 20.0f - 1.0f) * M_PI * 2.0f) / 5.0;
00961 }
00962 }
00963 }
00964
00965 m_texItem[m_texCur].MakeQuad();
00966
00967 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00968 float rotate = 60.0f * t;
00969 float scale = 1.0f - t;
00970
00971 glMatrixMode(GL_MODELVIEW);
00972 glLoadIdentity();
00973 glRotatef(rotate, 1.0f, 0.0f, 0.0f);
00974 glScalef(scale, scale, scale);
00975 glTranslatef(t, t, 0.0f);
00976
00977 ta.Bind();
00978
00979 glBegin(GL_QUADS);
00980 {
00981 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00982
00983 float float_x, float_y, float_xb, float_yb;
00984 int x, y;
00985
00986 for (x = 0; x < 39; x++)
00987 {
00988 for (y = 0; y < 39; y++)
00989 {
00990 float_x = (float) x / 40.0f;
00991 float_y = (float) y / 40.0f;
00992 float_xb = (float) (x + 1) / 40.0f;
00993 float_yb = (float) (y + 1) / 40.0f;
00994 glTexCoord2f(float_x, float_y);
00995 glVertex3f(m_effect_flutter_points[x][y][0],
00996 m_effect_flutter_points[x][y][1],
00997 m_effect_flutter_points[x][y][2]);
00998 glTexCoord2f(float_x, float_yb);
00999 glVertex3f(m_effect_flutter_points[x][y + 1][0],
01000 m_effect_flutter_points[x][y + 1][1],
01001 m_effect_flutter_points[x][y + 1][2]);
01002 glTexCoord2f(float_xb, float_yb);
01003 glVertex3f(m_effect_flutter_points[x + 1][y + 1][0],
01004 m_effect_flutter_points[x + 1][y + 1][1],
01005 m_effect_flutter_points[x + 1][y + 1][2]);
01006 glTexCoord2f(float_xb, float_y);
01007 glVertex3f(m_effect_flutter_points[x + 1][y][0],
01008 m_effect_flutter_points[x + 1][y][1],
01009 m_effect_flutter_points[x + 1][y][2]);
01010 }
01011 }
01012 }
01013 glEnd();
01014
01015
01016 if (m_effect_current_frame%2 == 0)
01017 {
01018
01019 float hold;
01020 int x, y;
01021 for (y = 0; y < 40; y++)
01022 {
01023 hold = m_effect_flutter_points[0][y][2];
01024 for (x = 0; x < 39; x++)
01025 {
01026 m_effect_flutter_points[x][y][2] = m_effect_flutter_points[x + 1][y][2];
01027 }
01028 m_effect_flutter_points[39][y][2] = hold;
01029 }
01030 }
01031 m_effect_current_frame++;
01032 }
01033
01034 void GLSingleView::EffectCube(void)
01035 {
01036 float tot = m_effect_transition_timeout ? m_effect_transition_timeout : 1.0f;
01037 float rotStart = 0.25f * m_effect_transition_timeout;
01038
01039 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
01040 {
01041 paintTexture();
01042 m_effect_running = false;
01043 m_slideshow_frame_delay_state = -1;
01044 return;
01045 }
01046
01047
01048 glEnable(GL_DEPTH_TEST);
01049 glDepthFunc(GL_LEQUAL);
01050 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
01051
01052 GLTexture &ta = m_texItem[(m_texCur) ? 0 : 1];
01053 GLTexture &tb = m_texItem[m_texCur];
01054
01055 glMatrixMode(GL_PROJECTION);
01056 glLoadIdentity();
01057
01058
01059 float znear = 3.0f;
01060
01061
01062
01063 glFrustum(-1.0f, 1.0f, -1.0f, 1.0f, znear - 0.01f, 10.0f);
01064
01065 if (m_effect_current_frame == 0)
01066 {
01067 m_effect_cube_xrot = 0.0f;
01068 m_effect_cube_yrot = 0.0f;
01069 m_effect_cube_zrot = 0.0f;
01070 }
01071
01072 glMatrixMode(GL_MODELVIEW);
01073 glLoadIdentity();
01074
01075 float elapsed = (float) m_effect_frame_time.elapsed();
01076 float tmp = ((elapsed <= tot * 0.5) ? elapsed : tot - elapsed);
01077 float trans = 5.0f * tmp / tot;
01078
01079 glTranslatef(0.0f, 0.0f, -znear - 1.0f - trans);
01080
01081 glRotatef(m_effect_cube_xrot, 1.0f, 0.0f, 0.0f);
01082 glRotatef(m_effect_cube_yrot, 0.0f, 1.0f, 0.0f);
01083
01084 glBindTexture(GL_TEXTURE_2D, 0);
01085
01086 glBegin(GL_QUADS);
01087 {
01088 glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
01089
01090
01091 glVertex3f(-1.00f, -1.00f, 0.99f);
01092 glVertex3f( 1.00f, -1.00f, 0.99f);
01093 glVertex3f( 1.00f, 1.00f, 0.99f);
01094 glVertex3f(-1.00f, 1.00f, 0.99f);
01095
01096
01097 glVertex3f(-1.00f, -1.00f, -0.99f);
01098 glVertex3f(-1.00f, 1.00f, -0.99f);
01099 glVertex3f( 1.00f, 1.00f, -0.99f);
01100 glVertex3f( 1.00f, -1.00f, -0.99f);
01101
01102
01103 glVertex3f(-1.00f, 0.99f, -1.00f);
01104 glVertex3f(-1.00f, 0.99f, 1.00f);
01105 glVertex3f( 1.00f, 0.99f, 1.00f);
01106 glVertex3f( 1.00f, 0.99f, -1.00f);
01107
01108
01109 glVertex3f(-1.00f, -0.99f, -1.00f);
01110 glVertex3f( 1.00f, -0.99f, -1.00f);
01111 glVertex3f( 1.00f, -0.99f, 1.00f);
01112 glVertex3f(-1.00f, -0.99f, 1.00f);
01113
01114
01115 glVertex3f(0.99f, -1.00f, -1.00f);
01116 glVertex3f(0.99f, 1.00f, -1.00f);
01117 glVertex3f(0.99f, 1.00f, 1.00f);
01118 glVertex3f(0.99f, -1.00f, 1.00f);
01119
01120
01121 glVertex3f(-0.99f, -1.00f, -1.00f);
01122 glVertex3f(-0.99f, -1.00f, 1.00f);
01123 glVertex3f(-0.99f, 1.00f, 1.00f);
01124 glVertex3f(-0.99f, 1.00f, -1.00f);
01125
01126 }
01127 glEnd();
01128
01129 ta.Bind();
01130
01131 glBegin(GL_QUADS);
01132 {
01133 glColor4d(1.0f, 1.0f, 1.0f, 1.0f);
01134
01135
01136 glTexCoord2f(0.0f, 0.0f);
01137 glVertex3f(-ta.GetTextureX(), -ta.GetTextureY(), 1.00f);
01138 glTexCoord2f(1.0f, 0.0f);
01139 glVertex3f(+ta.GetTextureX(), -ta.GetTextureY(), 1.00f);
01140 glTexCoord2f(1.0f, 1.0f);
01141 glVertex3f(+ta.GetTextureX(), +ta.GetTextureY(), 1.00f);
01142 glTexCoord2f(0.0f, 1.0f);
01143 glVertex3f(-ta.GetTextureX(), +ta.GetTextureY(), 1.00f);
01144
01145
01146 glTexCoord2f(1.0f, 1.0f);
01147 glVertex3f(-ta.GetTextureX(), 1.00f, -ta.GetTextureY());
01148 glTexCoord2f(1.0f, 0.0f);
01149 glVertex3f(-ta.GetTextureX(), 1.00f, +ta.GetTextureY());
01150 glTexCoord2f(0.0f, 0.0f);
01151 glVertex3f(+ta.GetTextureX(), 1.00f, +ta.GetTextureY());
01152 glTexCoord2f(0.0f, 1.0f);
01153 glVertex3f(+ta.GetTextureX(), 1.00f, -ta.GetTextureY());
01154
01155
01156 glTexCoord2f(0.0f, 1.0f);
01157 glVertex3f(-ta.GetTextureX(), -1.00f, -ta.GetTextureY());
01158 glTexCoord2f(1.0f, 1.0f);
01159 glVertex3f(+ta.GetTextureX(), -1.00f, -ta.GetTextureY());
01160 glTexCoord2f(1.0f, 0.0f);
01161 glVertex3f(+ta.GetTextureX(), -1.00f, +ta.GetTextureY());
01162 glTexCoord2f(0.0f, 0.0f);
01163 glVertex3f(-ta.GetTextureX(), -1.00f, +ta.GetTextureY());
01164
01165
01166 glTexCoord2f(0.0f, 0.0f);
01167 glVertex3f(1.00f, -ta.GetTextureX(), -ta.GetTextureY());
01168 glTexCoord2f(0.0f, 1.0f);
01169 glVertex3f(1.00f, -ta.GetTextureX(), +ta.GetTextureY());
01170 glTexCoord2f(1.0f, 1.0f);
01171 glVertex3f(1.00f, +ta.GetTextureX(), +ta.GetTextureY());
01172 glTexCoord2f(1.0f, 0.0f);
01173 glVertex3f(1.00f, +ta.GetTextureX(), -ta.GetTextureY());
01174
01175
01176 glTexCoord2f(1.0f, 0.0f);
01177 glVertex3f(-1.00f, -ta.GetTextureX(), -ta.GetTextureY());
01178 glTexCoord2f(0.0f, 0.0f);
01179 glVertex3f(-1.00f, +ta.GetTextureX(), -ta.GetTextureY());
01180 glTexCoord2f(0.0f, 1.0f);
01181 glVertex3f(-1.00f, +ta.GetTextureX(), +ta.GetTextureY());
01182 glTexCoord2f(1.0f, 1.0f);
01183 glVertex3f(-1.00f, -ta.GetTextureX(), +ta.GetTextureY());
01184 }
01185 glEnd();
01186
01187 tb.Bind();
01188
01189 glBegin(GL_QUADS);
01190 {
01191 glColor4d(1.0f, 1.0f, 1.0f, 1.0f);
01192
01193
01194 glTexCoord2f(1.0f, 0.0f);
01195 glVertex3f(-tb.GetTextureX(), -tb.GetTextureY(), -1.00f);
01196 glTexCoord2f(1.0f, 1.0f);
01197 glVertex3f(-tb.GetTextureX(), +tb.GetTextureY(), -1.00f);
01198 glTexCoord2f(0.0f, 1.0f);
01199 glVertex3f(+tb.GetTextureX(), +tb.GetTextureY(), -1.00f);
01200 glTexCoord2f(0.0f, 0.0f);
01201 glVertex3f(+tb.GetTextureX(), -tb.GetTextureY(), -1.00f);
01202 }
01203 glEnd();
01204
01205 if ((elapsed >= rotStart) && (elapsed < (tot - rotStart)))
01206 {
01207 m_effect_cube_xrot = 360.0f * (elapsed - rotStart) / (tot - 2 * rotStart);
01208 m_effect_cube_yrot = 0.5f * m_effect_cube_xrot;
01209 }
01210
01211 m_effect_current_frame++;
01212 }
01213
01214 void GLSingleView::EffectKenBurns(void)
01215 {
01216
01217 float single_image_pct = 0.75;
01218 float trans_pct = 1.0 - single_image_pct;
01219 float scale_max, x_loc, y_loc;
01220 float scale_factor = 0;
01221
01222
01223 if (!m_effect_kenBurns_initialized)
01224 {
01225
01226 m_effect_kenBurns_initialized = !m_effect_kenBurns_initialized;
01227 m_effect_kenBurns_item = NULL;
01228
01229 m_effect_kenBurns_imageLoadThread = new KenBurnsImageLoader(this, m_itemList, m_texSize, m_screenSize);
01230
01231 m_effect_kenBurns_image_time[m_texCur ? 0 : 1].restart();
01232
01233 FindRandXY(m_effect_kenBurns_location_x[0], m_effect_kenBurns_location_y[0]);
01234
01235 m_effect_kenBurns_projection[0] = 1;
01236 m_effect_kenBurns_projection[1] = 1;
01237 m_effect_kenBurns_image_timeout = m_effect_transition_timeout +
01238 (m_effect_transition_timeout * trans_pct);
01239 }
01240
01241 if (m_effect_frame_time.elapsed() >= m_effect_transition_timeout)
01242 {
01243
01244 m_tex1First = !m_tex1First;
01245 m_texCur = (m_texCur) ? 0 : 1;
01246 m_effect_current_frame = 0;
01247 m_effect_frame_time.restart();
01248
01249 m_effect_kenBurns_image_ready = false;
01250
01251
01252 int oldpos = m_pos;
01253
01254 while (true)
01255 {
01256 m_pos = m_slideshow_sequence->next();
01257 m_effect_kenBurns_item = m_itemList.at(m_pos);
01258 if (m_effect_kenBurns_item)
01259 {
01260
01261 if (QFile::exists(m_effect_kenBurns_item->GetPath()) && !GalleryUtil::IsMovie(m_effect_kenBurns_item->GetPath()))
01262 {
01263 break;
01264 }
01265 }
01266 if (m_pos == oldpos)
01267 {
01268
01269 close();
01270 }
01271 }
01272 m_effect_kenBurns_imageLoadThread->Initialize(m_pos);
01273 m_effect_kenBurns_imageLoadThread->start();
01274 }
01275
01276 float t[2], elapsed[2], s[2], effect_pct;
01277 elapsed[m_texCur] = m_effect_kenBurns_image_time[m_texCur].elapsed();
01278 elapsed[m_texCur ? 0 : 1] = m_effect_kenBurns_image_time[m_texCur ? 0 : 1].elapsed();
01279
01280 t[m_texCur] = elapsed[m_texCur] / m_effect_kenBurns_image_timeout;
01281 t[m_texCur ? 0 : 1] = elapsed[m_texCur ? 0 : 1] / m_effect_kenBurns_image_timeout;
01282
01283
01284 s[m_texCur] = sqrt(elapsed[m_texCur]) / sqrt(m_effect_kenBurns_image_timeout);
01285 s[m_texCur ? 0 : 1] = sqrt(elapsed[m_texCur ? 0 : 1]) / sqrt(m_effect_kenBurns_image_timeout);
01286
01287 effect_pct = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
01288
01289
01290 if (effect_pct > single_image_pct && m_effect_kenBurns_image_ready)
01291 {
01292 if (!m_effect_kenBurns_new_image_started)
01293 {
01294 if (m_effect_kenBurns_item)
01295 {
01296 m_texItem[!m_tex1First].SetItem(m_effect_kenBurns_item, m_effect_kenBurns_orig_image_size);
01297 m_texItem[!m_tex1First].ScaleTo(m_screenSize, m_scaleMax);
01298 m_texItem[!m_tex1First].Init(m_effect_kenBurns_image);
01299 UpdateLCD(m_effect_kenBurns_item);
01300
01301
01302 FindRandXY(m_effect_kenBurns_location_x[m_texCur],
01303 m_effect_kenBurns_location_y[m_texCur]);
01304 m_effect_kenBurns_projection[m_texCur] =
01305 1 + (int)((2.0f * random() / (RAND_MAX + 1.0f)));
01306 }
01307 else
01308 {
01309
01310 FindRandXY(m_effect_kenBurns_location_x[m_texCur], m_effect_kenBurns_location_y[m_texCur]);
01311 m_effect_kenBurns_projection[m_texCur] = 1;
01312 }
01313
01314 m_effect_kenBurns_image_time[m_texCur].restart();
01315 m_effect_kenBurns_new_image_started = true;
01316 }
01317 if (m_effect_kenBurns_projection[m_texCur] == 1)
01318 {
01319
01320 x_loc = m_effect_kenBurns_location_x[m_texCur] * t[m_texCur];
01321 y_loc = m_effect_kenBurns_location_y[m_texCur] * t[m_texCur];
01322 scale_max = FindMaxScale(x_loc,y_loc);
01323 scale_factor = 1.0f + (scale_max * s[m_texCur]);
01324 }
01325 else
01326 {
01327
01328 x_loc = m_effect_kenBurns_location_x[m_texCur] - m_effect_kenBurns_location_x[m_texCur] * t[m_texCur];
01329 y_loc = m_effect_kenBurns_location_y[m_texCur] - m_effect_kenBurns_location_y[m_texCur] * t[m_texCur];
01330 scale_max = FindMaxScale(x_loc,y_loc);
01331 scale_factor = 1.0f + scale_max - (scale_max * t[m_texCur]);
01332 }
01333
01334 glMatrixMode(GL_MODELVIEW);
01335 glLoadIdentity();
01336 glTranslatef(x_loc, y_loc, 0.0f);
01337
01338 m_texItem[m_texCur].MakeQuad((effect_pct-single_image_pct)*4, scale_factor);
01339 }
01340
01341
01342 if (m_effect_kenBurns_projection[m_texCur ? 0 : 1] == 1)
01343 {
01344 x_loc = m_effect_kenBurns_location_x[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
01345 y_loc = m_effect_kenBurns_location_y[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
01346 scale_max = FindMaxScale(x_loc,y_loc);
01347 scale_factor = 1.0f + (scale_max * s[m_texCur ? 0 : 1]);
01348 }
01349 else
01350 {
01351 x_loc = m_effect_kenBurns_location_x[m_texCur ? 0 : 1] -
01352 m_effect_kenBurns_location_x[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
01353 y_loc = m_effect_kenBurns_location_y[m_texCur ? 0 : 1] -
01354 m_effect_kenBurns_location_y[m_texCur ? 0 : 1] * t[m_texCur ? 0 : 1];
01355 scale_max = FindMaxScale(x_loc,y_loc);
01356 scale_factor = 1.0f + scale_max - (scale_max * t[m_texCur ? 0 : 1]);
01357 }
01358
01359 glMatrixMode(GL_MODELVIEW);
01360 glLoadIdentity();
01361 glTranslatef(x_loc, y_loc, 0.0f);
01362
01363 if (effect_pct<= single_image_pct)
01364 {
01365 m_effect_kenBurns_new_image_started=false;
01366 m_texItem[m_texCur ? 0 : 1].MakeQuad(1.0f, scale_factor);
01367 }
01368 else
01369 {
01370 m_texItem[m_texCur ? 0 : 1].MakeQuad(1.0f - ((effect_pct-single_image_pct)*4), scale_factor);
01371
01372 }
01373
01374 m_effect_current_frame++;
01375 }
01376
01377 void GLSingleView::SlideTimeout(void)
01378 {
01379 bool wasMovie = false, isMovie = false;
01380 if (m_effect_method.isEmpty())
01381 {
01382 LOG(VB_GENERAL, LOG_ERR, LOC + "No transition method");
01383 return;
01384 }
01385
01386 if (m_effect_running)
01387 {
01388 m_slideshow_frame_delay_state = 10;
01389 }
01390 else
01391 {
01392 if (m_slideshow_frame_delay_state == -1)
01393 {
01394
01395
01396 m_slideshow_frame_delay_state = m_slideshow_frame_delay * 1000;
01397 m_effect_current_frame = 0;
01398 }
01399 else
01400 {
01401
01402
01403
01404 if (m_slideshow_running)
01405 {
01406 if (m_effect_random)
01407 m_effect_method = GetRandomEffect();
01408
01409 DisplayNext(false, false);
01410
01411 wasMovie = m_movieState > 0;
01412 Load();
01413 isMovie = m_movieState > 0;
01414
01415
01416 if (wasMovie || isMovie)
01417 {
01418 m_slideshow_frame_delay_state = 1;
01419 }
01420 else
01421 {
01422 m_slideshow_frame_delay_state = 10;
01423 m_effect_running = true;
01424 m_effect_current_frame = 0;
01425 }
01426 m_effect_frame_time.restart();
01427 }
01428 m_info_show_short = false;
01429 }
01430 }
01431
01432 updateGL();
01433 if (m_slideshow_running)
01434 {
01435 m_slideshow_timer->stop();
01436 m_slideshow_timer->setSingleShot(true);
01437 m_slideshow_timer->start(max(0, m_slideshow_frame_delay_state));
01438
01439
01440
01441 if (wasMovie || isMovie)
01442 {
01443 m_slideshow_frame_delay_state = -1;
01444 }
01445 }
01446 }
01447
01448 void GLSingleView::createTexInfo(void)
01449 {
01450 if (m_texInfo)
01451 glDeleteTextures(1, &m_texInfo);
01452
01453 QString info = m_texItem[m_texCur].GetDescription(GetDescriptionStatus());
01454 if (info.isEmpty())
01455 return;
01456
01457 QPixmap pix(512, 512);
01458
01459 QPainter p(&pix);
01460 p.initFrom(this);
01461 p.fillRect(0, 0, pix.width(), pix.height(), Qt::black);
01462 p.setPen(Qt::white);
01463
01464 p.drawText(10, 10, pix.width() - 20, pix.height() - 20,
01465 Qt::AlignLeft, info);
01466 p.end();
01467
01468 QImage img = pix.toImage();
01469 img = img.convertToFormat(QImage::Format_ARGB32);
01470
01471 QImage tex = convertToGLFormat(img);
01472
01473
01474 glGenTextures(1, &m_texInfo);
01475 glBindTexture(GL_TEXTURE_2D, m_texInfo);
01476
01477 glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
01478 GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());
01479
01480 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
01481 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
01482 }
01483
01484 void GLSingleView::LoadImage(QImage image, QSize origSize)
01485 {
01486 m_effect_kenBurns_image = image;
01487 m_effect_kenBurns_orig_image_size = origSize;
01488 }
01489
01490 float GLSingleView::FindMaxScale(float x_loc, float y_loc)
01491 {
01492
01493 if (abs(x_loc) > abs(y_loc))
01494 return abs(x_loc) * 2;
01495 else
01496 return abs(y_loc) * 2;
01497 }
01498
01499 void GLSingleView::FindRandXY(float &x_loc, float &y_loc)
01500 {
01501
01502 x_loc = (0.5 * random() / (RAND_MAX + 1.0f)) + 0.25;
01503 if ((int)(2.0 * random() / (RAND_MAX + 1.0f)) == 0)
01504 x_loc = -1 * x_loc;
01505
01506 y_loc = (0.5 * random() / (RAND_MAX + 1.0f)) + 0.25;
01507 if ((int)(2.0 * random() / (RAND_MAX + 1.0f)) == 0)
01508 y_loc = -1 * y_loc;
01509 }
01510
01511 KenBurnsImageLoader::KenBurnsImageLoader(GLSingleView *singleView,
01512 ThumbList &itemList,
01513 QSize texSize, QSize screenSize) :
01514 MThread("KenBurnsImageLoader"),
01515 m_singleView(singleView),
01516 m_itemList(itemList),
01517 m_pos(0),
01518 m_tex1First(false),
01519 m_screenSize(screenSize),
01520 m_texSize(texSize)
01521 {
01522 }
01523
01524 void KenBurnsImageLoader::Initialize(int pos)
01525 {
01526 m_pos = pos;
01527 }
01528
01529 void KenBurnsImageLoader::run()
01530 {
01531 RunProlog();
01532 ThumbItem *item = m_itemList.at(m_pos);
01533 if (!item)
01534 {
01535 LOG(VB_GENERAL, LOG_ERR, LOC + QString("No item at %1").arg(m_pos));
01536 RunEpilog();
01537 return;
01538 }
01539 QImage image(item->GetPath());
01540 if (image.isNull())
01541 {
01542 RunEpilog();
01543 return;
01544 }
01545
01546 image = image.scaled(m_texSize, Qt::IgnoreAspectRatio,
01547 Qt::SmoothTransformation);
01548 QImage glimage = QGLWidget::convertToGLFormat(image);
01549
01550 m_singleView->LoadImage(glimage, glimage.size());
01551 m_singleView->Ready();
01552
01553 RunEpilog();
01554 }