|
MythTV
0.26-pre
|
00001 /* ============================================================ 00002 * File : glsingleview.cpp 00003 * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu> 00004 * Date : 2004-01-13 00005 * Description : 00006 * 00007 * Copyright 2004 by Renchi Raju 00008 * 00009 * This program is free software; you can redistribute it 00010 * and/or modify it under the terms of the GNU General 00011 * Public License as published bythe Free Software Foundation; 00012 * either version 2, or (at your option) 00013 * any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * ============================================================ */ 00021 00022 // Include own header first to catch missing includes 00023 #include "glsingleview.h" 00024 00025 // ANSI C headers 00026 #include <cmath> 00027 00028 // C++ headers 00029 #include <algorithm> 00030 using namespace std; 00031 00032 // Qt headers 00033 #include <QTimer> 00034 #include <QImage> 00035 #include <QDir> 00036 #include <QPainter> 00037 #include <qbuffer.h> 00038 00039 // MythTV plugin headers 00040 #include <mythcontext.h> 00041 #include <mythmiscutil.h> 00042 #include <mythuihelper.h> 00043 #include "mythlogging.h" 00044 00045 // MythGallery headers 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 // Have to clean up with this dirty hack because 00065 // qglwidget segfaults with a destructive close 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 // General 00080 m_source_x(0.0f), 00081 m_source_y(0.0f), 00082 m_scaleMax(kScaleToFit), 00083 00084 // Texture variables (for display and effects) 00085 m_texMaxDim(512), 00086 m_texSize(512,512), 00087 m_texCur(0), 00088 m_tex1First(true), 00089 00090 // Info variables 00091 m_texInfo(0), 00092 00093 // Common effect state variables 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 // Unshared effect state variables 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 // save the current m_scaleMax setting so we can restore it later 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 // Enable Texture Mapping 00174 glEnable(GL_TEXTURE_2D); 00175 // Clear The Background Color 00176 glClearColor(0.0, 0.0, 0.0, 1.0f); 00177 00178 // Turn Blending On 00179 glEnable(GL_BLEND); 00180 // Blending Function For Translucency Based On Source Alpha Value 00181 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00182 00183 // Enable perspective vision 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 // Reset The Current Viewport And Perspective Transformation 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 // overlay "Press SELECT to play again" text 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 // Search for next item that hasn't been deleted. 00548 // Close viewer if none remain. 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 // No valid items!!! 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 // Search for next item that hasn't been deleted. 00587 // Close viewer in none remain. 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 // No valid items!!! 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 //if (effect == "EffectNone") 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 // wave every two iterations 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 // Enable perspective vision 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 // float PI = 4.0f * atan(1.0f); 01059 float znear = 3.0f; 01060 // float theta = 2.0f * atan2(2.0f / 2.0f, znear); 01061 // theta = theta * 180.0f/PI; 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 /* Front Face */ 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 /* Back Face */ 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 /* Top Face */ 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 /* Bottom Face */ 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 /* Right face */ 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 /* Left Face */ 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 // Front Face 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 // Top Face 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 // Bottom Face 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 // Right face 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 // Left Face 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 // Back Face 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 //initialize effect 01223 if (!m_effect_kenBurns_initialized) 01224 { 01225 01226 m_effect_kenBurns_initialized = !m_effect_kenBurns_initialized; 01227 m_effect_kenBurns_item = NULL; 01228 // Need to load images in the background to keep effect smooth 01229 m_effect_kenBurns_imageLoadThread = new KenBurnsImageLoader(this, m_itemList, m_texSize, m_screenSize); 01230 //Since total image time is longer/different than effect time, create image timers 01231 m_effect_kenBurns_image_time[m_texCur ? 0 : 1].restart(); 01232 // Pan image to a random location 01233 FindRandXY(m_effect_kenBurns_location_x[0], m_effect_kenBurns_location_y[0]); 01234 // Since first two images are preloaded, hardcode them to zoom in 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 // Effect timed out, move new image to old image but don't load new image yet... 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 // Find next image to be loaded 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 // Skip movies 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 // No valid items!!! 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 //progress linearly 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 //progress faster initially then slowing down- this is needed to ensure images zoom faster than they pan and 01283 //therefore stay completely on the screen 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 // Load new image if its ready 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) //Do not create textures for first two images, since they are preloaded 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 //choose the location and projection (zoom in or out) randomly 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 //No item, must be 1 of the first two preloaded items 01308 { 01309 //start at random location and zoom out to face in center 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) // Zoom in image 01318 { 01319 // Start in center and pan out 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 // Zoom out image 01326 { 01327 // Start at random location and pan to center 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 //Load old picture 01342 if (m_effect_kenBurns_projection[m_texCur ? 0 : 1] == 1)// Zoom in image 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 // Zoom out image 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 // Fade out image 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 // effect was running and is complete now 01395 // run timer while showing current image 01396 m_slideshow_frame_delay_state = m_slideshow_frame_delay * 1000; 01397 m_effect_current_frame = 0; 01398 } 01399 else 01400 { 01401 // timed out after showing current image 01402 // load next image and start effect 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 // If transitioning to/from a movie, don't do an effect, 01415 // and shorten timeout 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 // If transitioning to/from a movie, no effect is running so 01440 // next timeout should trigger proper immage delay. 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 /* create the texture */ 01474 glGenTextures(1, &m_texInfo); 01475 glBindTexture(GL_TEXTURE_2D, m_texInfo); 01476 /* actually generate the texture */ 01477 glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0, 01478 GL_RGBA, GL_UNSIGNED_BYTE, tex.bits()); 01479 /* enable linear filtering */ 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 // Zoom big enough to keep the entire image on screen when we pan 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 // Random number between .25 and .75 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 // Random number between .25 and .75 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 }
1.7.6.1