00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cmath>
00024
00025
00026 #include <algorithm>
00027 using namespace std;
00028
00029
00030 #include <qtimer.h>
00031 #include <qimage.h>
00032 #include <qlayout.h>
00033 #include <qsize.h>
00034 #include <qdir.h>
00035 #include <qpainter.h>
00036
00037
00038 #include <mythtv/mythcontext.h>
00039 #include <mythtv/util.h>
00040
00041
00042 #include "glsingleview.h"
00043 #include "galleryutil.h"
00044
00045 #define LOC QString("GLView: ")
00046 #define LOC_ERR QString("GLView, Error: ")
00047
00048 GLSDialog::GLSDialog(const ThumbList& itemList,
00049 int pos, int slideShow, int sortOrder,
00050 MythMainWindow *parent, const char *name)
00051 : MythDialog(parent, name)
00052 {
00053 QBoxLayout *l = new QVBoxLayout(this);
00054 m_view = new GLSingleView(itemList, pos, slideShow, sortOrder, this);
00055 l->addWidget(m_view);
00056
00057 setFocusProxy(m_view);
00058 m_view->setFocus();
00059 }
00060
00061
00062
00063
00064 void GLSDialog::closeEvent(QCloseEvent *e)
00065 {
00066 m_view->CleanUp();
00067 e->accept();
00068 }
00069
00070 GLSingleView::GLSingleView(ThumbList itemList, int pos, int slideShow,
00071 int sortorder, QWidget *parent)
00072 : QGLWidget(parent),
00073 ImageView(itemList, pos, slideShow, sortorder),
00074
00075 m_source_x(0.0f),
00076 m_source_y(0.0f),
00077 m_scaleMax(false),
00078
00079
00080 m_texMaxDim(512),
00081 m_texSize(512,512),
00082 m_texCur(0),
00083 m_tex1First(true),
00084
00085
00086 m_texInfo(0),
00087
00088
00089 m_effect_rotate_direction(0),
00090 m_effect_transition_timeout(2000),
00091 m_effect_transition_timeout_inv(1.0f / m_effect_transition_timeout),
00092
00093
00094 m_effect_cube_xrot(0.0f),
00095 m_effect_cube_yrot(0.0f),
00096 m_effect_cube_zrot(0.0f)
00097 {
00098 m_scaleMax = (gContext->GetNumSetting("GalleryScaleMax", 0) > 0);
00099
00100 m_slideshow_timer = new QTimer(this);
00101 RegisterEffects();
00102
00103
00104
00105 setFocusPolicy(QWidget::WheelFocus);
00106
00107
00108
00109 QString transType = gContext->GetSetting("SlideshowOpenGLTransition");
00110 if (!transType.isEmpty() && m_effect_map.contains(transType))
00111 m_effect_method = m_effect_map[transType];
00112
00113 if (!m_effect_method || transType == QString("random (gl)"))
00114 {
00115 m_effect_method = GetRandomEffect();
00116 m_effect_random = true;
00117 }
00118
00119 SetTransitionTimeout(gContext->GetNumSetting(
00120 "SlideshowOpenGLTransitionLength", 2000));
00121
00122
00123
00124 connect(m_slideshow_timer, SIGNAL(timeout()), this, SLOT(SlideTimeout()));
00125
00126
00127
00128 if (slideShow)
00129 {
00130 m_slideshow_running = true;
00131 m_slideshow_timer->start(m_slideshow_frame_delay_state, true);
00132 gContext->DisableScreensaver();
00133 }
00134 }
00135
00136 GLSingleView::~GLSingleView()
00137 {
00138
00139 gContext->SaveSetting("GalleryScaleMax", (m_scaleMax ? "1" : "0"));
00140 }
00141
00142 void GLSingleView::CleanUp(void)
00143 {
00144 makeCurrent();
00145
00146 if (m_slideshow_timer)
00147 {
00148 m_slideshow_timer->stop();
00149 m_slideshow_timer->deleteLater();
00150 m_slideshow_timer = NULL;
00151 }
00152
00153 m_texItem[0].Deinit();
00154 m_texItem[1].Deinit();
00155
00156 if (m_texInfo)
00157 glDeleteTextures(1, &m_texInfo);
00158 }
00159
00160 void GLSingleView::initializeGL(void)
00161 {
00162
00163 glEnable(GL_TEXTURE_2D);
00164
00165 glClearColor(0.0, 0.0, 0.0, 1.0f);
00166
00167
00168 glEnable(GL_BLEND);
00169
00170 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00171
00172
00173 glClearDepth(1.0f);
00174
00175 GLint param;
00176 glGetIntegerv(GL_MAX_TEXTURE_SIZE, ¶m);
00177 m_texMaxDim = param;
00178
00179 m_texSize = QSize(GetNearestGLTextureSize(m_screenSize.width()),
00180 GetNearestGLTextureSize(m_screenSize.height()));
00181
00182 Load();
00183 }
00184
00185 void GLSingleView::resizeGL(int w, int h)
00186 {
00187
00188 glViewport(0, 0, (GLint)w, (GLint)h);
00189
00190 glMatrixMode(GL_PROJECTION);
00191 glLoadIdentity();
00192 }
00193
00194 void GLSingleView::paintGL(void)
00195 {
00196 if (m_movieState > 0)
00197 {
00198 if (m_movieState == 1)
00199 {
00200 m_movieState = 2;
00201 ThumbItem* item = m_itemList.at(m_pos);
00202 QString path = QString("\"") + item->GetPath() + "\"";
00203 QString cmd = gContext->GetSetting("GalleryMoviePlayerCmd");
00204 cmd.replace("%s", path);
00205 myth_system(cmd);
00206 if (!m_slideshow_running)
00207 {
00208 close();
00209 }
00210 }
00211 return;
00212 }
00213
00214 glDisable(GL_DEPTH_TEST);
00215
00216 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00217 glLoadIdentity();
00218
00219 glMatrixMode(GL_PROJECTION);
00220 glLoadIdentity();
00221
00222 glMatrixMode(GL_MODELVIEW);
00223 glLoadIdentity();
00224
00225 if (m_effect_running && !m_effect_method.isEmpty())
00226 {
00227 RunEffect(m_effect_method);
00228 }
00229 else
00230 {
00231 paintTexture();
00232 }
00233
00234 if (glGetError())
00235 VERBOSE(VB_GENERAL, LOC_ERR + "OpenGL error detected");
00236 }
00237
00238 void GLSingleView::keyPressEvent(QKeyEvent *e)
00239 {
00240 bool handled = false;
00241
00242 bool wasRunning = m_slideshow_running;
00243 m_slideshow_timer->stop();
00244 m_slideshow_running = false;
00245 gContext->RestoreScreensaver();
00246 m_effect_running = false;
00247 m_slideshow_frame_delay_state = m_slideshow_frame_delay * 1000;
00248
00249 bool wasInfo = m_info_show;
00250 m_info_show = false;
00251 bool wasInfoShort = m_info_show_short;
00252 m_info_show_short = false;
00253
00254 QStringList actions;
00255 gContext->GetMainWindow()->TranslateKeyPress("Gallery", e, actions);
00256
00257 float scrollX = 0.2f;
00258 float scrollY = 0.2f;
00259
00260 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00261 {
00262 QString action = actions[i];
00263 handled = true;
00264
00265 if (action == "LEFT" || action == "UP")
00266 {
00267 m_info_show = wasInfo;
00268 m_slideshow_running = wasRunning;
00269 DisplayPrev(true, true);
00270 }
00271 else if (action == "RIGHT" || action == "DOWN")
00272 {
00273 m_info_show = wasInfo;
00274 m_slideshow_running = wasRunning;
00275 DisplayNext(true, true);
00276 }
00277 else if (action == "ZOOMOUT")
00278 {
00279 if (m_zoom > 0.5f)
00280 {
00281 SetZoom(m_zoom - 0.5f);
00282 if (m_zoom > 1.0f)
00283 {
00284 m_source_x -= m_source_x / ((m_zoom + 0.5) * 2.0f);
00285 m_source_y -= m_source_y / ((m_zoom + 0.5) * 2.0f);
00286
00287 checkPosition();
00288 }
00289 else
00290 {
00291 m_source_x = 0;
00292 m_source_y = 0;
00293 }
00294 }
00295 }
00296 else if (action == "ZOOMIN")
00297 {
00298 if (m_zoom < 4.0f)
00299 {
00300 SetZoom(m_zoom + 0.5f);
00301 if (m_zoom > 1.0f)
00302 {
00303 m_source_x += m_source_x / (m_zoom * 2.0f);
00304 m_source_y += m_source_y / (m_zoom * 2.0f);
00305
00306 checkPosition();
00307 }
00308 else
00309 {
00310 m_source_x = 0;
00311 m_source_y = 0;
00312 }
00313 }
00314 }
00315 else if (action == "FULLSIZE")
00316 {
00317 m_source_x = 0;
00318 m_source_y = 0;
00319 if (m_zoom != 1)
00320 SetZoom(1.0f);
00321 }
00322 else if (action == "SCROLLLEFT")
00323 {
00324 if (m_zoom > 1.0f && m_source_x < m_zoom - 1.0f)
00325 {
00326 m_source_x += scrollX;
00327 m_source_x = min(m_source_x, m_zoom - 1.0f);
00328 }
00329 }
00330 else if (action == "SCROLLRIGHT")
00331 {
00332 if (m_zoom > 1.0f && m_source_x > -m_zoom + 1.0f)
00333 {
00334 m_source_x -= scrollX;
00335 m_source_x = max(m_source_x, -m_zoom + 1.0f);
00336 }
00337 }
00338 else if (action == "SCROLLUP")
00339 {
00340 if (m_zoom > 1.0f && m_source_y < m_zoom - 1.0f)
00341 {
00342 m_source_y += scrollY;
00343 m_source_y = min(m_source_y, m_zoom - 1.0f);
00344 }
00345 }
00346 else if (action == "SCROLLDOWN")
00347 {
00348 if (m_zoom > 1.0f && m_source_y > -m_zoom + 1.0f)
00349 {
00350 m_source_y -= scrollY;
00351 m_source_y = max(m_source_y, -m_zoom + 1.0f);
00352 }
00353 }
00354 else if (action == "RECENTER")
00355 {
00356 if (m_zoom > 1.0f)
00357 {
00358 m_source_x = 0.0f;
00359 m_source_y = 0.0f;
00360 }
00361 }
00362 else if (action == "UPLEFT")
00363 {
00364 if (m_zoom > 1.0f)
00365 {
00366 m_source_x = 1.0f;
00367 m_source_y = -1.0f;
00368 }
00369 }
00370 else if (action == "LOWRIGHT")
00371 {
00372 if (m_zoom > 1.0f)
00373 {
00374 m_source_x = -1.0f;
00375 m_source_y = 1.0f;
00376 }
00377 }
00378 else if (action == "ROTRIGHT")
00379 {
00380 m_source_x = 0;
00381 m_source_y = 0;
00382 Rotate(90);
00383 }
00384 else if (action == "ROTLEFT")
00385 {
00386 m_source_x = 0;
00387 m_source_y = 0;
00388 Rotate(-90);
00389 }
00390 else if (action == "DELETE")
00391 {
00392 ThumbItem *item = m_itemList.at(m_pos);
00393 if (item && GalleryUtil::Delete(item->GetPath()))
00394 {
00395 item->SetPixmap(NULL);
00396 DisplayNext(true, true);
00397 }
00398 m_info_show = wasInfo;
00399 m_slideshow_running = wasRunning;
00400 }
00401 else if (action == "PLAY" || action == "SLIDESHOW" ||
00402 action == "RANDOMSHOW")
00403 {
00404 m_source_x = 0;
00405 m_source_y = 0;
00406 SetZoom(1.0f);
00407 m_info_show = wasInfo;
00408 m_info_show_short = true;
00409 m_slideshow_running = !wasRunning;
00410 }
00411 else if (action == "INFO")
00412 {
00413 m_info_show = !wasInfo && !wasInfoShort;
00414 m_slideshow_running = wasRunning;
00415 }
00416 else if (action == "FULLSCREEN")
00417 {
00418 m_scaleMax = !m_scaleMax;
00419 m_source_x = 0;
00420 m_source_y = 0;
00421 SetZoom(1.0f);
00422 Load();
00423 }
00424 else
00425 {
00426 handled = false;
00427 }
00428 }
00429
00430 if (m_slideshow_running || m_info_show_short)
00431 {
00432 m_slideshow_timer->start(m_slideshow_frame_delay_state, true);
00433 }
00434
00435 if (m_slideshow_running)
00436 {
00437 gContext->DisableScreensaver();
00438 }
00439
00440 updateGL();
00441
00442 if (handled)
00443 {
00444 e->accept();
00445 }
00446 else {
00447 e->ignore();
00448 }
00449 }
00450
00451 void GLSingleView::checkPosition(void)
00452 {
00453 m_source_x = max(m_source_x, -m_zoom + 1.0f);
00454 m_source_y = max(m_source_y, -m_zoom + 1.0f);
00455 m_source_x = min(m_source_x, m_zoom - 1.0f);
00456 m_source_y = min(m_source_y, m_zoom - 1.0f);
00457 }
00458
00459 void GLSingleView::paintTexture(void)
00460 {
00461 glMatrixMode(GL_MODELVIEW);
00462 glLoadIdentity();
00463
00464 glTranslatef(m_source_x, m_source_y, 0.0f);
00465 glScalef(m_zoom, m_zoom, 1.0f);
00466
00467 m_texItem[m_texCur].MakeQuad();
00468
00469 if (m_info_show || m_info_show_short)
00470 {
00471 createTexInfo();
00472
00473 glMatrixMode(GL_MODELVIEW);
00474 glLoadIdentity();
00475
00476 glMatrixMode(GL_TEXTURE);
00477 glLoadIdentity();
00478
00479 glBindTexture(GL_TEXTURE_2D, m_texInfo);
00480 glBegin(GL_QUADS);
00481 {
00482 glColor4f(1.0f, 1.0f, 1.0f, 0.72f);
00483 glTexCoord2f(0.0f, 0.0f);
00484 glVertex3f(-0.75f, -0.75f, 0.0f);
00485
00486 glTexCoord2f(1.0f, 0.0f);
00487 glVertex3f(+0.75f, -0.75f, 0.0f);
00488
00489 glTexCoord2f(1.0f, 1.0f);
00490 glVertex3f(+0.75f, +0.75f, 0.0f);
00491
00492 glTexCoord2f(0.0f, 1.0f);
00493 glVertex3f(-0.75f, +0.75f, 0.0f);
00494 }
00495 glEnd();
00496 }
00497 }
00498
00499 void GLSingleView::DisplayNext(bool reset, bool loadImage)
00500 {
00501 if (reset)
00502 {
00503 m_zoom = 1.0f;
00504 m_source_x = 0.0f;
00505 m_source_y = 0.0f;
00506 }
00507
00508
00509
00510 ThumbItem *item;
00511 int oldpos = m_pos;
00512
00513 while (true)
00514 {
00515 m_pos = m_slideshow_sequence->next();
00516 item = m_itemList.at(m_pos);
00517 if (item)
00518 {
00519 if (QFile::exists(item->GetPath()))
00520 {
00521 break;
00522 }
00523 }
00524 if (m_pos == oldpos)
00525 {
00526
00527 close();
00528 }
00529 }
00530
00531 m_tex1First = !m_tex1First;
00532 m_texCur = (m_texCur) ? 0 : 1;
00533
00534 if (loadImage)
00535 Load();
00536 }
00537
00538 void GLSingleView::DisplayPrev(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 int oldpos = m_pos;
00550 while (true)
00551 {
00552 m_pos = m_slideshow_sequence->prev();
00553
00554 ThumbItem *item = m_itemList.at(m_pos);
00555 if (item && QFile::exists(item->GetPath()))
00556 break;
00557
00558 if (m_pos == oldpos)
00559 {
00560
00561 close();
00562 }
00563 };
00564
00565 m_tex1First = !m_tex1First;
00566 m_texCur = (m_texCur) ? 0 : 1;
00567
00568 if (loadImage)
00569 Load();
00570 }
00571
00572 void GLSingleView::Load(void)
00573 {
00574 m_movieState = 0;
00575 ThumbItem *item = m_itemList.at(m_pos);
00576 if (!item)
00577 {
00578 VERBOSE(VB_IMPORTANT, LOC_ERR + "No item at "<<m_pos);
00579 return;
00580 }
00581
00582 if (GalleryUtil::isMovie(item->GetPath()))
00583 {
00584 m_movieState = 1;
00585 return;
00586 }
00587
00588 QImage image(item->GetPath());
00589 if (image.isNull())
00590 return;
00591
00592 int a = m_tex1First ? 0 : 1;
00593 m_texItem[a].SetItem(item, image.size());
00594 m_texItem[a].ScaleTo(m_screenSize, m_scaleMax);
00595 m_texItem[a].Init(convertToGLFormat(image.smoothScale(m_texSize)));
00596
00597 UpdateLCD(item);
00598 }
00599
00600 void GLSingleView::Rotate(int angle)
00601 {
00602 int ang = m_texItem[m_texCur].GetAngle() + angle;
00603
00604 ang = (ang >= 360) ? ang - 360 : ang;
00605 ang = (ang < 0) ? ang + 360 : ang;
00606
00607 m_texItem[m_texCur].SetAngle(ang);
00608
00609 ThumbItem *item = m_itemList.at(m_pos);
00610 if (item)
00611 item->SetRotationAngle(ang);
00612
00613 m_texItem[m_texCur].SwapWidthHeight();
00614 m_texItem[m_texCur].ScaleTo(m_screenSize, m_scaleMax);
00615 }
00616
00617 void GLSingleView::SetZoom(float zoom)
00618 {
00619 m_zoom = zoom;
00620 }
00621
00622 void GLSingleView::SetTransitionTimeout(int timeout)
00623 {
00624 m_effect_transition_timeout = timeout;
00625 m_effect_transition_timeout_inv = 1.0f;
00626 if (timeout)
00627 m_effect_transition_timeout_inv = 1.0f / timeout;
00628 }
00629
00630 int GLSingleView::GetNearestGLTextureSize(int v) const
00631 {
00632 int n = 0, last = 0;
00633 int s;
00634
00635 for (s = 0; s < 32; ++s)
00636 {
00637 if (((v >> s) & 1) == 1)
00638 {
00639 ++n;
00640 last = s;
00641 }
00642 }
00643
00644 if (n > 1)
00645 s = 1 << (last + 1);
00646 else
00647 s = 1 << last;
00648
00649 return min(s, m_texMaxDim);
00650 }
00651
00652 void GLSingleView::RegisterEffects(void)
00653 {
00654 m_effect_map.insert("none", "EffectNone");
00655 m_effect_map.insert("blend (gl)", "EffectBlend");
00656 m_effect_map.insert("zoom blend (gl)", "EffectZoomBlend");
00657 m_effect_map.insert("fade (gl)", "EffectFade");
00658 m_effect_map.insert("rotate (gl)", "EffectRotate");
00659 m_effect_map.insert("bend (gl)", "EffectBend");
00660 m_effect_map.insert("inout (gl)", "EffectInOut");
00661 m_effect_map.insert("slide (gl)", "EffectSlide");
00662 m_effect_map.insert("flutter (gl)", "EffectFlutter");
00663 m_effect_map.insert("cube (gl)", "EffectCube");
00664 }
00665
00666 void GLSingleView::RunEffect(const QString &effect)
00667 {
00668 if (effect == "EffectBlend")
00669 EffectBlend();
00670 else if (effect == "EffectZoomBlend")
00671 EffectZoomBlend();
00672 else if (effect == "EffectFade")
00673 EffectFade();
00674 else if (effect == "EffectRotate")
00675 EffectRotate();
00676 else if (effect == "EffectBend")
00677 EffectBend();
00678 else if (effect == "EffectInOut")
00679 EffectInOut();
00680 else if (effect == "EffectSlide")
00681 EffectSlide();
00682 else if (effect == "EffectFlutter")
00683 EffectFlutter();
00684 else if (effect == "EffectCube")
00685 EffectCube();
00686 else
00687 EffectNone();
00688 }
00689
00690 void GLSingleView::EffectNone(void)
00691 {
00692 paintTexture();
00693 m_effect_running = false;
00694 m_slideshow_frame_delay_state = -1;
00695 return;
00696 }
00697
00698 void GLSingleView::EffectBlend(void)
00699 {
00700 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00701 {
00702 paintTexture();
00703 m_effect_running = false;
00704 m_slideshow_frame_delay_state = -1;
00705 return;
00706 }
00707
00708 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00709
00710 m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
00711
00712 glBegin(GL_QUADS);
00713 {
00714 glColor4f(0.0f, 0.0f, 0.0f, 1.0f * t);
00715 glVertex3f(-1.0f, -1.0f, 0.0f);
00716 glVertex3f(+1.0f, -1.0f, 0.0f);
00717 glVertex3f(+1.0f, +1.0f, 0.0f);
00718 glVertex3f(-1.0f, +1.0f, 0.0f);
00719 }
00720 glEnd();
00721
00722 m_texItem[m_texCur].MakeQuad(t);
00723
00724 m_effect_current_frame++;
00725 }
00726
00727 void GLSingleView::EffectZoomBlend(void)
00728 {
00729 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00730 {
00731 paintTexture();
00732 m_effect_running = false;
00733 m_slideshow_frame_delay_state = -1;
00734 return;
00735 }
00736
00737 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00738
00739 m_texItem[m_texCur ? 0 : 1].MakeQuad(1.0f - t, 1.0f + (0.75 * t));
00740 m_texItem[m_texCur].MakeQuad(t);
00741
00742 m_effect_current_frame++;
00743 }
00744
00745 void GLSingleView::EffectRotate(void)
00746 {
00747 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00748 {
00749 paintTexture();
00750 m_effect_running = false;
00751 m_slideshow_frame_delay_state = -1;
00752 return;
00753 }
00754
00755 if (m_effect_current_frame == 0)
00756 m_effect_rotate_direction = (int)((2.0*rand()/(RAND_MAX+1.0)));
00757
00758 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00759
00760 m_texItem[m_texCur].MakeQuad();
00761
00762 glMatrixMode(GL_MODELVIEW);
00763 glLoadIdentity();
00764 float rotate = 360.0f * t;
00765 glRotatef(((m_effect_rotate_direction == 0) ? -1 : 1) * rotate,
00766 0.0f, 0.0f, 1.0f);
00767 float scale = 1.0f * (1.0f - t);
00768 glScalef(scale, scale, 1.0f);
00769
00770 m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
00771
00772 m_effect_current_frame++;
00773 }
00774
00775 void GLSingleView::EffectBend(void)
00776 {
00777 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00778 {
00779 paintTexture();
00780 m_effect_running = false;
00781 m_slideshow_frame_delay_state = -1;
00782 return;
00783 }
00784
00785 if (m_effect_current_frame == 0)
00786 m_effect_rotate_direction = (int)((2.0f*rand()/(RAND_MAX+1.0f)));
00787
00788 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00789
00790 m_texItem[m_texCur].MakeQuad();
00791
00792 glMatrixMode(GL_MODELVIEW);
00793 glLoadIdentity();
00794 glRotatef(90.0f * t,
00795 (m_effect_rotate_direction == 0) ? 1.0f : 0.0f,
00796 (m_effect_rotate_direction == 1) ? 1.0f : 0.0f,
00797 0.0f);
00798
00799 m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
00800
00801 m_effect_current_frame++;
00802 }
00803
00804 void GLSingleView::EffectFade(void)
00805 {
00806 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00807 {
00808 paintTexture();
00809 m_effect_running = false;
00810 m_slideshow_frame_delay_state = -1;
00811 return;
00812 }
00813
00814 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00815
00816 if (m_effect_frame_time.elapsed() <= m_effect_transition_timeout / 2)
00817 m_texItem[(m_texCur) ? 0 : 1].MakeQuad(1.0f - (2.0f * t));
00818 else
00819 m_texItem[m_texCur].MakeQuad(2.0f * (t - 0.5f));
00820
00821 m_effect_current_frame++;
00822 }
00823
00824 void GLSingleView::EffectInOut(void)
00825 {
00826 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00827 {
00828 paintTexture();
00829 m_effect_running = false;
00830 m_slideshow_frame_delay_state = -1;
00831 return;
00832 }
00833
00834 if (m_effect_current_frame == 0)
00835 {
00836 m_effect_rotate_direction = 1 + (int)((4.0f*rand()/(RAND_MAX+1.0f)));
00837 }
00838
00839 int texnum = m_texCur;
00840 bool fadeout = false;
00841 if (m_effect_frame_time.elapsed() <= m_effect_transition_timeout / 2)
00842 {
00843 texnum = (m_texCur) ? 0 : 1;
00844 fadeout = true;
00845 }
00846
00847 glMatrixMode(GL_MODELVIEW);
00848 glLoadIdentity();
00849
00850 float tt = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00851 float t = 2.0f / ((fadeout) ? (0.5f - tt) : (tt - 0.5f));
00852
00853 glScalef(t, t, 1.0f);
00854 t = 1.0f - t;
00855 glTranslatef((m_effect_rotate_direction % 2 == 0) ? ((m_effect_rotate_direction == 2)? 1 : -1) * t : 0.0f,
00856 (m_effect_rotate_direction % 2 == 1) ? ((m_effect_rotate_direction == 1)? 1 : -1) * t : 0.0f,
00857 0.0f);
00858
00859 m_texItem[texnum].MakeQuad();
00860
00861 m_effect_current_frame++;
00862 }
00863
00864 void GLSingleView::EffectSlide(void)
00865 {
00866 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00867 {
00868 paintTexture();
00869 m_effect_running = false;
00870 m_slideshow_frame_delay_state = -1;
00871 return;
00872 }
00873
00874 if (m_effect_current_frame == 0)
00875 m_effect_rotate_direction = 1 + (int)((4.0f * rand() / (RAND_MAX + 1.0f)));
00876
00877 m_texItem[m_texCur].MakeQuad();
00878
00879 glMatrixMode(GL_MODELVIEW);
00880 glLoadIdentity();
00881 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00882 float trans = 2.0f * t;
00883 glTranslatef((m_effect_rotate_direction % 2 == 0) ? ((m_effect_rotate_direction == 2)? 1 : -1) * trans : 0.0f,
00884 (m_effect_rotate_direction % 2 == 1) ? ((m_effect_rotate_direction == 1)? 1 : -1) * trans : 0.0f,
00885 0.0f);
00886
00887 m_texItem[(m_texCur) ? 0 : 1].MakeQuad();
00888
00889 m_effect_current_frame++;
00890 }
00891
00892 void GLSingleView::EffectFlutter(void)
00893 {
00894 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00895 {
00896 paintTexture();
00897 m_effect_running = false;
00898 m_slideshow_frame_delay_state = -1;
00899 return;
00900 }
00901
00902 GLTexture &ta = m_texItem[(m_texCur) ? 0 : 1];
00903
00904 if (m_effect_current_frame == 0)
00905 {
00906 for (int x = 0; x < 40; x++)
00907 {
00908 for (int y = 0; y < 40; y++)
00909 {
00910 m_effect_flutter_points[x][y][0] =
00911 (float) (x / 20.0f - 1.0f) * ta.GetTextureX();
00912 m_effect_flutter_points[x][y][1] =
00913 (float) (y / 20.0f - 1.0f) * ta.GetTextureY();
00914 m_effect_flutter_points[x][y][2] =
00915 (float) sin((x / 20.0f - 1.0f) * M_PI * 2.0f) / 5.0;
00916 }
00917 }
00918 }
00919
00920 m_texItem[m_texCur].MakeQuad();
00921
00922 float t = m_effect_frame_time.elapsed() * m_effect_transition_timeout_inv;
00923 float rotate = 60.0f * t;
00924 float scale = 1.0f - t;
00925
00926 glMatrixMode(GL_MODELVIEW);
00927 glLoadIdentity();
00928 glRotatef(rotate, 1.0f, 0.0f, 0.0f);
00929 glScalef(scale, scale, scale);
00930 glTranslatef(t, t, 0.0f);
00931
00932 ta.Bind();
00933
00934 glBegin(GL_QUADS);
00935 {
00936 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00937
00938 float float_x, float_y, float_xb, float_yb;
00939 int x, y;
00940
00941 for (x = 0; x < 39; x++)
00942 {
00943 for (y = 0; y < 39; y++)
00944 {
00945 float_x = (float) x / 40.0f;
00946 float_y = (float) y / 40.0f;
00947 float_xb = (float) (x + 1) / 40.0f;
00948 float_yb = (float) (y + 1) / 40.0f;
00949 glTexCoord2f(float_x, float_y);
00950 glVertex3f(m_effect_flutter_points[x][y][0],
00951 m_effect_flutter_points[x][y][1],
00952 m_effect_flutter_points[x][y][2]);
00953 glTexCoord2f(float_x, float_yb);
00954 glVertex3f(m_effect_flutter_points[x][y + 1][0],
00955 m_effect_flutter_points[x][y + 1][1],
00956 m_effect_flutter_points[x][y + 1][2]);
00957 glTexCoord2f(float_xb, float_yb);
00958 glVertex3f(m_effect_flutter_points[x + 1][y + 1][0],
00959 m_effect_flutter_points[x + 1][y + 1][1],
00960 m_effect_flutter_points[x + 1][y + 1][2]);
00961 glTexCoord2f(float_xb, float_y);
00962 glVertex3f(m_effect_flutter_points[x + 1][y][0],
00963 m_effect_flutter_points[x + 1][y][1],
00964 m_effect_flutter_points[x + 1][y][2]);
00965 }
00966 }
00967 }
00968 glEnd();
00969
00970
00971 if (m_effect_current_frame%2 == 0)
00972 {
00973
00974 float hold;
00975 int x, y;
00976 for (y = 0; y < 40; y++)
00977 {
00978 hold = m_effect_flutter_points[0][y][2];
00979 for (x = 0; x < 39; x++)
00980 {
00981 m_effect_flutter_points[x][y][2] = m_effect_flutter_points[x + 1][y][2];
00982 }
00983 m_effect_flutter_points[39][y][2] = hold;
00984 }
00985 }
00986 m_effect_current_frame++;
00987 }
00988
00989 void GLSingleView::EffectCube(void)
00990 {
00991 float tot = m_effect_transition_timeout ? m_effect_transition_timeout : 1.0f;
00992 float rotStart = 0.25f * m_effect_transition_timeout;
00993
00994 if (m_effect_frame_time.elapsed() > m_effect_transition_timeout)
00995 {
00996 paintTexture();
00997 m_effect_running = false;
00998 m_slideshow_frame_delay_state = -1;
00999 return;
01000 }
01001
01002
01003 glEnable(GL_DEPTH_TEST);
01004 glDepthFunc(GL_LEQUAL);
01005 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
01006
01007 GLTexture &ta = m_texItem[(m_texCur) ? 0 : 1];
01008 GLTexture &tb = m_texItem[m_texCur];
01009
01010 glMatrixMode(GL_PROJECTION);
01011 glLoadIdentity();
01012
01013 float PI = 4.0f * atan(1.0f);
01014 float znear = 3.0f;
01015 float theta = 2.0f * atan2(2.0f / 2.0f, znear);
01016 theta = theta * 180.0f/PI;
01017
01018 glFrustum(-1.0f, 1.0f, -1.0f, 1.0f, znear - 0.01f, 10.0f);
01019
01020 if (m_effect_current_frame == 0)
01021 {
01022 m_effect_cube_xrot = 0.0f;
01023 m_effect_cube_yrot = 0.0f;
01024 m_effect_cube_zrot = 0.0f;
01025 }
01026
01027 glMatrixMode(GL_MODELVIEW);
01028 glLoadIdentity();
01029
01030 float elapsed = (float) m_effect_frame_time.elapsed();
01031 float tmp = ((elapsed <= tot * 0.5) ? elapsed : tot - elapsed);
01032 float trans = 5.0f * tmp / tot;
01033
01034 glTranslatef(0.0f, 0.0f, -znear - 1.0f - trans);
01035
01036 glRotatef(m_effect_cube_xrot, 1.0f, 0.0f, 0.0f);
01037 glRotatef(m_effect_cube_yrot, 0.0f, 1.0f, 0.0f);
01038
01039 glBindTexture(GL_TEXTURE_2D, 0);
01040
01041 glBegin(GL_QUADS);
01042 {
01043 glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
01044
01045
01046 glVertex3f(-1.00f, -1.00f, 0.99f);
01047 glVertex3f( 1.00f, -1.00f, 0.99f);
01048 glVertex3f( 1.00f, 1.00f, 0.99f);
01049 glVertex3f(-1.00f, 1.00f, 0.99f);
01050
01051
01052 glVertex3f(-1.00f, -1.00f, -0.99f);
01053 glVertex3f(-1.00f, 1.00f, -0.99f);
01054 glVertex3f( 1.00f, 1.00f, -0.99f);
01055 glVertex3f( 1.00f, -1.00f, -0.99f);
01056
01057
01058 glVertex3f(-1.00f, 0.99f, -1.00f);
01059 glVertex3f(-1.00f, 0.99f, 1.00f);
01060 glVertex3f( 1.00f, 0.99f, 1.00f);
01061 glVertex3f( 1.00f, 0.99f, -1.00f);
01062
01063
01064 glVertex3f(-1.00f, -0.99f, -1.00f);
01065 glVertex3f( 1.00f, -0.99f, -1.00f);
01066 glVertex3f( 1.00f, -0.99f, 1.00f);
01067 glVertex3f(-1.00f, -0.99f, 1.00f);
01068
01069
01070 glVertex3f(0.99f, -1.00f, -1.00f);
01071 glVertex3f(0.99f, 1.00f, -1.00f);
01072 glVertex3f(0.99f, 1.00f, 1.00f);
01073 glVertex3f(0.99f, -1.00f, 1.00f);
01074
01075
01076 glVertex3f(-0.99f, -1.00f, -1.00f);
01077 glVertex3f(-0.99f, -1.00f, 1.00f);
01078 glVertex3f(-0.99f, 1.00f, 1.00f);
01079 glVertex3f(-0.99f, 1.00f, -1.00f);
01080
01081 }
01082 glEnd();
01083
01084 ta.Bind();
01085
01086 glBegin(GL_QUADS);
01087 {
01088 glColor4d(1.0f, 1.0f, 1.0f, 1.0f);
01089
01090
01091 glTexCoord2f(0.0f, 0.0f);
01092 glVertex3f(-ta.GetTextureX(), -ta.GetTextureY(), 1.00f);
01093 glTexCoord2f(1.0f, 0.0f);
01094 glVertex3f(+ta.GetTextureX(), -ta.GetTextureY(), 1.00f);
01095 glTexCoord2f(1.0f, 1.0f);
01096 glVertex3f(+ta.GetTextureX(), +ta.GetTextureY(), 1.00f);
01097 glTexCoord2f(0.0f, 1.0f);
01098 glVertex3f(-ta.GetTextureX(), +ta.GetTextureY(), 1.00f);
01099
01100
01101 glTexCoord2f(1.0f, 1.0f);
01102 glVertex3f(-ta.GetTextureX(), 1.00f, -ta.GetTextureY());
01103 glTexCoord2f(1.0f, 0.0f);
01104 glVertex3f(-ta.GetTextureX(), 1.00f, +ta.GetTextureY());
01105 glTexCoord2f(0.0f, 0.0f);
01106 glVertex3f(+ta.GetTextureX(), 1.00f, +ta.GetTextureY());
01107 glTexCoord2f(0.0f, 1.0f);
01108 glVertex3f(+ta.GetTextureX(), 1.00f, -ta.GetTextureY());
01109
01110
01111 glTexCoord2f(0.0f, 1.0f);
01112 glVertex3f(-ta.GetTextureX(), -1.00f, -ta.GetTextureY());
01113 glTexCoord2f(1.0f, 1.0f);
01114 glVertex3f(+ta.GetTextureX(), -1.00f, -ta.GetTextureY());
01115 glTexCoord2f(1.0f, 0.0f);
01116 glVertex3f(+ta.GetTextureX(), -1.00f, +ta.GetTextureY());
01117 glTexCoord2f(0.0f, 0.0f);
01118 glVertex3f(-ta.GetTextureX(), -1.00f, +ta.GetTextureY());
01119
01120
01121 glTexCoord2f(0.0f, 0.0f);
01122 glVertex3f(1.00f, -ta.GetTextureX(), -ta.GetTextureY());
01123 glTexCoord2f(0.0f, 1.0f);
01124 glVertex3f(1.00f, -ta.GetTextureX(), +ta.GetTextureY());
01125 glTexCoord2f(1.0f, 1.0f);
01126 glVertex3f(1.00f, +ta.GetTextureX(), +ta.GetTextureY());
01127 glTexCoord2f(1.0f, 0.0f);
01128 glVertex3f(1.00f, +ta.GetTextureX(), -ta.GetTextureY());
01129
01130
01131 glTexCoord2f(1.0f, 0.0f);
01132 glVertex3f(-1.00f, -ta.GetTextureX(), -ta.GetTextureY());
01133 glTexCoord2f(0.0f, 0.0f);
01134 glVertex3f(-1.00f, +ta.GetTextureX(), -ta.GetTextureY());
01135 glTexCoord2f(0.0f, 1.0f);
01136 glVertex3f(-1.00f, +ta.GetTextureX(), +ta.GetTextureY());
01137 glTexCoord2f(1.0f, 1.0f);
01138 glVertex3f(-1.00f, -ta.GetTextureX(), +ta.GetTextureY());
01139 }
01140 glEnd();
01141
01142 tb.Bind();
01143
01144 glBegin(GL_QUADS);
01145 {
01146 glColor4d(1.0f, 1.0f, 1.0f, 1.0f);
01147
01148
01149 glTexCoord2f(1.0f, 0.0f);
01150 glVertex3f(-tb.GetTextureX(), -tb.GetTextureY(), -1.00f);
01151 glTexCoord2f(1.0f, 1.0f);
01152 glVertex3f(-tb.GetTextureX(), +tb.GetTextureY(), -1.00f);
01153 glTexCoord2f(0.0f, 1.0f);
01154 glVertex3f(+tb.GetTextureX(), +tb.GetTextureY(), -1.00f);
01155 glTexCoord2f(0.0f, 0.0f);
01156 glVertex3f(+tb.GetTextureX(), -tb.GetTextureY(), -1.00f);
01157 }
01158 glEnd();
01159
01160 if ((elapsed >= rotStart) && (elapsed < (tot - rotStart)))
01161 {
01162 m_effect_cube_xrot = 360.0f * (elapsed - rotStart) / (tot - 2 * rotStart);
01163 m_effect_cube_yrot = 0.5f * m_effect_cube_xrot;
01164 }
01165
01166 m_effect_current_frame++;
01167 }
01168
01169 void GLSingleView::SlideTimeout(void)
01170 {
01171 bool wasMovie = false, isMovie = false;
01172 if (m_effect_method.isEmpty())
01173 {
01174 VERBOSE(VB_IMPORTANT, LOC_ERR + "No transition method");
01175 return;
01176 }
01177
01178 if (m_effect_running)
01179 {
01180 m_slideshow_frame_delay_state = 10;
01181 }
01182 else
01183 {
01184 if (m_slideshow_frame_delay_state == -1)
01185 {
01186
01187
01188 m_slideshow_frame_delay_state = m_slideshow_frame_delay * 1000;
01189 m_effect_current_frame = 0;
01190 }
01191 else
01192 {
01193
01194
01195
01196 if (m_slideshow_running)
01197 {
01198 if (m_effect_random)
01199 m_effect_method = GetRandomEffect();
01200
01201 DisplayNext(false, false);
01202
01203 wasMovie = m_movieState > 0;
01204 Load();
01205 isMovie = m_movieState > 0;
01206
01207
01208 if (wasMovie || isMovie)
01209 {
01210 m_slideshow_frame_delay_state = 1;
01211 }
01212 else
01213 {
01214 m_slideshow_frame_delay_state = 10;
01215 m_effect_running = true;
01216 m_effect_current_frame = 0;
01217 }
01218 m_effect_frame_time.restart();
01219 }
01220 m_info_show_short = false;
01221 }
01222 }
01223
01224 updateGL();
01225 if (m_slideshow_running)
01226 {
01227 m_slideshow_timer->start(m_slideshow_frame_delay_state, true);
01228
01229
01230
01231 if (wasMovie || isMovie)
01232 {
01233 m_slideshow_frame_delay_state = -1;
01234 }
01235 }
01236 }
01237
01238 void GLSingleView::createTexInfo(void)
01239 {
01240 if (m_texInfo)
01241 glDeleteTextures(1, &m_texInfo);
01242
01243 QString info = m_texItem[m_texCur].GetDescription(GetDescriptionStatus());
01244 if (info.isEmpty())
01245 return;
01246
01247 QPixmap pix(512, 512);
01248
01249 QPainter p(&pix, this);
01250 p.fillRect(0, 0, pix.width(), pix.height(), Qt::black);
01251 p.setPen(Qt::white);
01252
01253 p.drawText(10, 10, pix.width() - 20, pix.height() - 20,
01254 Qt::AlignLeft, info);
01255 p.end();
01256
01257 QImage img(pix.convertToImage());
01258 img = img.convertDepth(32);
01259
01260 QImage tex = convertToGLFormat(img);
01261
01262
01263 glGenTextures(1, &m_texInfo);
01264 glBindTexture(GL_TEXTURE_2D, m_texInfo);
01265
01266 glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
01267 GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());
01268
01269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
01270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
01271 }