/* ============================================================ * File : slideshowgl.cpp * Author: Renchi Raju * Date : 2004-01-19 * Description : * * Copyright 2004 by Renchi Raju * Copyright 2007 by Valerio Fuoglio * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "slideshowgl.h" #include "toolbar.h" namespace KIPISlideShowPlugin { SlideShowGL::SlideShowGL(const TQValueList >& fileList, const TQStringList& commentsList, bool ImagesHasComments) : TQGLWidget(0, 0, 0, WStyle_StaysOnTop | WType_Popup | WX11BypassWM | WDestructiveClose) { #if KDE_IS_VERSION(3,2,0) TQRect deskRect = TDEGlobalSettings::desktopGeometry(this); m_deskX = deskRect.x(); m_deskY = deskRect.y(); m_deskWidth = deskRect.width(); m_deskHeight = deskRect.height(); #else TQRect deskRect = TQApplication::desktop()->screenGeometry(this); m_deskX = deskRect.x(); m_deskY = deskRect.y(); m_deskWidth = deskRect.width(); m_deskHeight = deskRect.height(); #endif move(m_deskX, m_deskY); resize(m_deskWidth, m_deskHeight); m_toolBar = new ToolBar(this); m_toolBar->hide(); if (!m_loop) { m_toolBar->setEnabledPrev(false); } connect(m_toolBar, TQT_SIGNAL(signalPause()), TQT_SLOT(slotPause())); connect(m_toolBar, TQT_SIGNAL(signalPlay()), TQT_SLOT(slotPlay())); connect(m_toolBar, TQT_SIGNAL(signalNext()), TQT_SLOT(slotNext())); connect(m_toolBar, TQT_SIGNAL(signalPrev()), TQT_SLOT(slotPrev())); connect(m_toolBar, TQT_SIGNAL(signalClose()), TQT_SLOT(slotClose())); // -- Minimal texture size (opengl specs) -------------- m_width = 64; m_height = 64; // -------------------------------------------------- m_fileList = fileList; m_commentsList = commentsList; m_imagesHasComments = ImagesHasComments; m_config = new TDEConfig("kipirc"); m_config->setGroup("SlideShow Settings"); readSettings(); // ------------------------------------------------------------------ m_fileIndex = 0; m_texture[0] = 0; m_texture[1] = 0; m_curr = 0; m_tex1First = true; m_timeout = m_delay; m_effectRunning = false; m_endOfShow = false; m_imageLoader = new SlideShowLoader(m_fileList, m_cacheSize, width(), height()); // -------------------------------------------------- registerEffects(); if (m_effectName == "Random") { m_effect = getRandomEffect(); m_random = true; } else { m_effect = m_effects[m_effectName]; if (!m_effect) m_effect = m_effects["None"]; m_random = false; } // -------------------------------------------------- m_timer = new TQTimer(); connect(m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeOut())); m_timer->start(m_timeout, true); // -- hide cursor when not moved -------------------- m_mouseMoveTimer = new TQTimer; connect(m_mouseMoveTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotMouseMoveTimeOut())); setMouseTracking(true); slotMouseMoveTimeOut(); } SlideShowGL::~SlideShowGL() { delete m_timer; delete m_mouseMoveTimer; if (m_texture[0]) glDeleteTextures(1, &m_texture[0]); if (m_texture[1]) glDeleteTextures(1, &m_texture[1]); if (m_imageLoader) delete m_imageLoader; if (m_config) delete m_config; } void SlideShowGL::readSettings() { m_delay = m_config->readNumEntry("Delay", 1500); m_printName = m_config->readBoolEntry("Print Filename", true); m_printProgress = m_config->readBoolEntry("Print Progress Indicator", true); m_printComments = m_config->readBoolEntry("Print Comments", false); m_loop = m_config->readBoolEntry("Loop", false); m_effectName = m_config->readEntry("Effect Name (OpenGL)", "Random"); m_enableMouseWheel = m_config->readBoolEntry("Enable Mouse Wheel", true); // Comments tab settings m_commentsFont = new TQFont(); m_commentsFont->setFamily(m_config->readEntry("Comments Font Family")); m_commentsFont->setPointSize(m_config->readNumEntry("Comments Font Size", 10 )); m_commentsFont->setBold(m_config->readBoolEntry("Comments Font Bold", false)); m_commentsFont->setItalic(m_config->readBoolEntry("Comments Font Italic", false)); m_commentsFont->setUnderline(m_config->readBoolEntry("Comments Font Underline", false)); m_commentsFont->setOverline(m_config->readBoolEntry("Comments Font Overline", false)); m_commentsFont->setStrikeOut(m_config->readBoolEntry("Comments Font StrikeOut", false)); m_commentsFont->setFixedPitch(m_config->readBoolEntry("Comments Font FixedPitch", false)); m_commentsFontColor = m_config->readUnsignedNumEntry("Comments Font Color", 0xffffff); m_commentsBgColor = m_config->readUnsignedNumEntry("Comments Bg Color", 0x000000); m_commentsLinesLength = m_config->readNumEntry("Comments Lines Length", 72); // Advanced settings bool enableCache = m_config->readBoolEntry("Enable Cache", false); if (enableCache) m_cacheSize = m_config->readNumEntry("Cache Size", 1); else m_cacheSize = 1; } void SlideShowGL::initializeGL() { // Enable Texture Mapping glEnable(GL_TEXTURE_2D); // Clear The Background Color glClearColor(0.0, 0.0, 0.0, 1.0f); // Turn Blending On glEnable(GL_BLEND); // Blending Function For Translucency Based On Source Alpha Value glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // Enable perspective vision glClearDepth(1.0f); // get the maximum texture value. GLint maxTexVal; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexVal); // allow only maximum texture value of 1024. anything bigger and things slow down maxTexVal = TQMIN(1024, maxTexVal); m_width = TQApplication::desktop()->width(); m_height = TQApplication::desktop()->height(); m_width = 1 << (int)ceil(log((float)m_width)/log((float)2)) ; m_height = 1 << (int)ceil(log((float)m_height)/log((float)2)); m_width = TQMIN( maxTexVal, m_width ); m_height = TQMIN( maxTexVal, m_height ); // load the first image loadImage(); } void SlideShowGL::paintGL() { glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (m_endOfShow) showEndOfShow(); else { if (m_effectRunning && m_effect) (this->*m_effect)(); else paintTexture(); } } void SlideShowGL::resizeGL(int w, int h) { // Reset The Current Viewport And Perspective Transformation glViewport(0, 0, (GLint)w, (GLint)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); } void SlideShowGL::keyPressEvent(TQKeyEvent *event) { if(!event) return; m_toolBar->keyPressEvent(event); } void SlideShowGL::mousePressEvent(TQMouseEvent *e) { if (m_endOfShow) slotClose(); if (e->button() == Qt::LeftButton) { m_timer->stop(); m_toolBar->setPaused(true); slotNext(); } else if (e->button() == Qt::RightButton && m_fileIndex-1 >= 0) { m_timer->stop(); m_toolBar->setPaused(true); slotPrev(); } } void SlideShowGL::mouseMoveEvent(TQMouseEvent *e) { setCursor(TQCursor(TQt::ArrowCursor)); m_mouseMoveTimer->start(1000, true); if (!m_toolBar->canHide()) return; TQPoint pos(e->pos()); if ((pos.y() > (m_deskY+20)) && (pos.y() < (m_deskY+m_deskHeight-20-1))) { if (m_toolBar->isHidden()) return; else m_toolBar->hide(); return; } int w = m_toolBar->width(); int h = m_toolBar->height(); if (pos.y() < (m_deskY+20)) { if (pos.x() <= (m_deskX+m_deskWidth/2)) // position top left m_toolBar->move(m_deskX, m_deskY); else // position top right m_toolBar->move(m_deskX+m_deskWidth-w-1, m_deskY); } else { if (pos.x() <= (m_deskX+m_deskWidth/2)) // position bot left m_toolBar->move(m_deskX, m_deskY+m_deskHeight-h-1); else // position bot right m_toolBar->move(m_deskX+m_deskWidth-w-1, m_deskY+m_deskHeight-h-1); } m_toolBar->show(); } void SlideShowGL::wheelEvent(TQWheelEvent *e) { if (!m_enableMouseWheel) return; if (m_endOfShow) slotClose(); int delta = e->delta(); if (delta < 0) { m_timer->stop(); m_toolBar->setPaused(true); slotNext(); } else if (delta > 0 && m_fileIndex-1 >= 0) { m_timer->stop(); m_toolBar->setPaused(true); slotPrev(); } } void SlideShowGL::registerEffects() { m_effects.insert("None", &SlideShowGL::effectNone); m_effects.insert("Blend", &SlideShowGL::effectBlend); m_effects.insert("Fade", &SlideShowGL::effectFade); m_effects.insert("Rotate", &SlideShowGL::effectRotate); m_effects.insert("Bend", &SlideShowGL::effectBend); m_effects.insert("In Out", &SlideShowGL::effectInOut); m_effects.insert("Slide", &SlideShowGL::effectSlide); m_effects.insert("Flutter", &SlideShowGL::effectFlutter); m_effects.insert("Cube", &SlideShowGL::effectCube); } TQStringList SlideShowGL::effectNames() { TQStringList effects; effects.append("None"); effects.append("Bend"); effects.append("Blend"); effects.append("Cube"); effects.append("Fade"); effects.append("Flutter"); effects.append("In Out"); effects.append("Rotate"); effects.append("Slide"); effects.append("Random"); return effects; } TQMap SlideShowGL::effectNamesI18N() { TQMap effects; effects["None"] = i18n("None"); effects["Bend"] = i18n("Bend"); effects["Blend"] = i18n("Blend"); effects["Cube"] = i18n("Cube"); effects["Fade"] = i18n("Fade"); effects["Flutter"] = i18n("Flutter"); effects["In Out"] = i18n("In Out"); effects["Rotate"] = i18n("Rotate"); effects["Slide"] = i18n("Slide"); effects["Random"] = i18n("Random"); return effects; } SlideShowGL::EffectMethod SlideShowGL::getRandomEffect() { TQMap tmpMap(m_effects); tmpMap.remove("None"); TQStringList t = tmpMap.keys(); int count = t.count(); int i = (int)((float)(count)*rand()/(RAND_MAX+1.0)); TQString key = t[i]; return tmpMap[key]; } void SlideShowGL::advanceFrame() { m_fileIndex++; m_imageLoader->next(); int num = m_fileList.count(); if (m_fileIndex >= num) { if (m_loop) { m_fileIndex = 0; } else { m_fileIndex = num-1; m_endOfShow = true; m_toolBar->setEnabledPlay(false); m_toolBar->setEnabledNext(false); m_toolBar->setEnabledPrev(false); } } if (!m_loop && !m_endOfShow) { m_toolBar->setEnabledPrev(m_fileIndex > 0); m_toolBar->setEnabledNext(m_fileIndex < num-1); } m_tex1First = !m_tex1First; m_curr = (m_curr == 0) ? 1 : 0; } void SlideShowGL::previousFrame() { m_fileIndex--; m_imageLoader->prev(); int num = m_fileList.count(); if (m_fileIndex < 0) { if (m_loop) { m_fileIndex = num-1; } else { m_fileIndex = 0; m_endOfShow = true; m_toolBar->setEnabledPlay(false); m_toolBar->setEnabledNext(false); m_toolBar->setEnabledPrev(false); } } if (!m_loop && !m_endOfShow) { m_toolBar->setEnabledPrev(m_fileIndex > 0); m_toolBar->setEnabledNext(m_fileIndex < num-1); } m_tex1First = !m_tex1First; m_curr = (m_curr == 0) ? 1 : 0; } void SlideShowGL::loadImage() { TQImage image = m_imageLoader->getCurrent(); if (!image.isNull()) { int a = m_tex1First ? 0 : 1; GLuint& tex = m_texture[a]; if (tex) glDeleteTextures(1, &tex); TQImage black(width(), height(), 32); black.fill(TQt::black.rgb()); /* image = image.smoothScale(width(), height(), TQ_ScaleMin);*/ montage(image, black); black = black.smoothScale(m_width, m_height); if (m_printName) printFilename(black); if (m_printProgress) printProgress(black); if (m_printComments && m_imagesHasComments) printComments(black); TQImage t = convertToGLFormat(black); /* create the texture */ glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); /* actually generate the texture */ glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() ); /* enable linear filtering */ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); } } void SlideShowGL::montage(TQImage& top, TQImage& bot) { int tw = top.width(); int th = top.height(); int bw = bot.width(); int bh = bot.height(); if (tw > bw || th > bh) tqFatal("Top Image should be smaller or same size as Bottom Image"); if (top.depth() != 32) top = top.convertDepth(32); if (bot.depth() != 32) bot = bot.convertDepth(32); int sw = bw/2 - tw/2; //int ew = bw/2 + tw/2; int sh = bh/2 - th/2; int eh = bh/2 + th/2; unsigned int *tdata = (unsigned int*) top.scanLine(0); unsigned int *bdata = 0; for (int y = sh; y < eh; y++) { bdata = (unsigned int*) bot.scanLine(y) + sw; for (int x = 0; x < tw; x++) { *(bdata++) = *(tdata++); } } } void SlideShowGL::printFilename(TQImage& layer) { TQFileInfo fileinfo(m_fileList[m_fileIndex].first); TQString filename = fileinfo.fileName(); TQFont fn(font()); fn.setPointSize(fn.pointSize()); fn.setBold(true); TQFontMetrics fm(fn); TQRect rect=fm.boundingRect(filename); rect.addCoords( 0, 0, 2, 2 ); TQPixmap pix(rect.width(),rect.height()); pix.fill(TQt::black); TQPainter p(&pix); p.setPen(TQt::white); p.setFont(fn); p.drawText(1,fn.pointSize()+1 , filename); p.end(); TQImage textimage(pix.convertToImage()); KImageEffect::blendOnLower(0,m_height-rect.height(),textimage,layer); } void SlideShowGL::printProgress(TQImage& layer) { TQString progress(TQString::number(m_fileIndex + 1) + "/" + TQString::number(m_fileList.count())); TQFont fn(font()); fn.setPointSize(fn.pointSize()); fn.setBold(true); TQFontMetrics fm(fn); TQRect rect=fm.boundingRect(progress); rect.addCoords( 0, 0, 2, 2 ); TQPixmap pix(rect.width(),rect.height()); pix.fill(TQt::black); TQPainter p(&pix); int stringLength = p.fontMetrics().width(progress) * progress.length(); p.setPen(TQt::white); p.setFont(fn); p.drawText(1,fn.pointSize()+1 , progress); p.end(); TQImage textimage(pix.convertToImage()); KImageEffect::blendOnLower(m_width - stringLength - 10, 20,textimage,layer); } void SlideShowGL::printComments(TQImage& layer) { TQString comments = m_commentsList[m_fileIndex]; int yPos = 5; // Text Y coordinate if (m_printName) yPos += 20; TQStringList commentsByLines; uint commentsIndex = 0; // Comments TQString index while (commentsIndex < comments.length()) { TQString newLine; bool breakLine = FALSE; // End Of Line found uint currIndex; // Comments TQString current index // Check miminal lines dimension int commentsLinesLengthLocal = m_commentsLinesLength; for ( currIndex = commentsIndex; currIndex < comments.length() && !breakLine; currIndex++ ) if( comments[currIndex] == TQChar('\n') || comments[currIndex].isSpace() ) breakLine = TRUE; if (commentsLinesLengthLocal <= (int)((currIndex - commentsIndex))) commentsLinesLengthLocal = (currIndex - commentsIndex); breakLine = FALSE; for ( currIndex = commentsIndex; currIndex <= commentsIndex + commentsLinesLengthLocal && currIndex < comments.length() && !breakLine; currIndex++ ) { breakLine = (comments[currIndex] == TQChar('\n')) ? TRUE : FALSE; if (breakLine) newLine.append( ' ' ); else newLine.append( comments[currIndex] ); } commentsIndex = currIndex; // The line is ended if ( commentsIndex != comments.length() ) while ( !newLine.endsWith(" ") ) { newLine.truncate(newLine.length() - 1); commentsIndex--; } commentsByLines.prepend(newLine.stripWhiteSpace()); } TQFontMetrics fm(*m_commentsFont); for ( int lineNumber = 0; lineNumber < (int)commentsByLines.count(); lineNumber++ ) { yPos += int(1.5 * m_commentsFont->pointSize()); TQRect rect=fm.boundingRect(commentsByLines[lineNumber]); rect.addCoords( 0, 0, 2, 2 ); TQPixmap pix(rect.width(),rect.height()); pix.fill(TQColor(m_commentsBgColor)); TQPainter p(&pix); p.setPen(TQColor(m_commentsFontColor)); p.setFont(*m_commentsFont); p.drawText(1,m_commentsFont->pointSize()+0 , commentsByLines[lineNumber]); p.end(); TQImage textimage(pix.convertToImage()); KImageEffect::blendOnLower(0,m_height-rect.height()-yPos,textimage,layer); } } void SlideShowGL::showEndOfShow() { TQPixmap pix(512,512); pix.fill(TQt::black); TQFont fn(font()); fn.setPointSize(fn.pointSize()+10); fn.setBold(true); TQPainter p(&pix); p.setPen(TQt::white); p.setFont(fn); p.drawText(20, 50, i18n("SlideShow Completed.")); p.drawText(20, 100, i18n("Click To Exit...")); p.end(); TQImage image(pix.convertToImage()); TQImage t = convertToGLFormat(image); GLuint tex; /* create the texture */ glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); /* actually generate the texture */ glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() ); /* enable linear filtering */ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); /* paint the texture */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBindTexture(GL_TEXTURE_2D, tex); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0, -1.0, 0); glTexCoord2f(1, 0); glVertex3f(1.0, -1.0, 0); glTexCoord2f(1, 1); glVertex3f(1.0, 1.0, 0); glTexCoord2f(0, 1); glVertex3f(-1.0, 1.0, 0); } glEnd(); } void SlideShowGL::slotTimeOut() { if (!m_effect) { kdWarning( 51000 ) << "SlideShowGL: No transition method" << endl; m_effect = &SlideShowGL::effectNone; } if (m_effectRunning) { m_timeout = 10; } else { if (m_timeout == -1) { // effect was running and is complete now // run timer while showing current image m_timeout = m_delay; m_i = 0; } else { // timed out after showing current image // load next image and start effect if (m_random) m_effect = getRandomEffect(); advanceFrame(); if (m_endOfShow) { updateGL(); return; } loadImage(); m_timeout = 10; m_effectRunning = true; m_i = 0; } } updateGL(); m_timer->start(m_timeout, true); } void SlideShowGL::slotMouseMoveTimeOut() { TQPoint pos(TQCursor::pos()); if ((pos.y() < (m_deskY+20)) || (pos.y() > (m_deskY+m_deskHeight-20-1))) return; setCursor(TQCursor(TQt::BlankCursor)); } void SlideShowGL::paintTexture() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); GLuint& tex = m_texture[m_curr]; glBindTexture(GL_TEXTURE_2D, tex); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0, -1.0, 0); glTexCoord2f(1, 0); glVertex3f(1.0, -1.0, 0); glTexCoord2f(1, 1); glVertex3f(1.0, 1.0, 0); glTexCoord2f(0, 1); glVertex3f(-1.0, 1.0, 0); } glEnd(); } void SlideShowGL::effectNone() { paintTexture(); m_effectRunning = false; m_timeout = -1; return; } void SlideShowGL::effectBlend() { if (m_i > 100) { paintTexture(); m_effectRunning = false; m_timeout = -1; return; } int a = (m_curr == 0) ? 1 : 0; int b = m_curr; GLuint& ta = m_texture[a]; GLuint& tb = m_texture[b]; glBindTexture(GL_TEXTURE_2D, ta); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); glBindTexture(GL_TEXTURE_2D, tb); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0/(100.0)*(float)m_i); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); m_i++; } void SlideShowGL::effectFade() { if (m_i > 100) { paintTexture(); m_effectRunning = false; m_timeout = -1; return; } int a; float opacity; if (m_i <= 50) { a = (m_curr == 0) ? 1 : 0; opacity = 1.0 - 1.0/50.0*(float)(m_i); } else { opacity = 1.0/50.0*(float)(m_i-50.0); a = m_curr; } GLuint& ta = m_texture[a]; glBindTexture(GL_TEXTURE_2D, ta); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, opacity); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); m_i++; } void SlideShowGL::effectRotate() { if (m_i > 100) { paintTexture(); m_effectRunning = false; m_timeout = -1; return; } if (m_i == 0) m_dir = (int)((2.0*rand()/(RAND_MAX+1.0))); int a = (m_curr == 0) ? 1 : 0; int b = m_curr; GLuint& ta = m_texture[a]; GLuint& tb = m_texture[b]; glBindTexture(GL_TEXTURE_2D, tb); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); float rotate = 360.0/100.0*(float)m_i; glRotatef( ((m_dir == 0) ? -1 : 1) * rotate, 0.0, 0.0, 1.0); float scale = 1.0/100.0*(100.0-(float)(m_i)); glScalef(scale,scale,1.0); glBindTexture(GL_TEXTURE_2D, ta); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); m_i++; } void SlideShowGL::effectBend() { if (m_i > 100) { paintTexture(); m_effectRunning = false; m_timeout = -1; return; } if (m_i == 0) m_dir = (int)((2.0*rand()/(RAND_MAX+1.0))); int a = (m_curr == 0) ? 1 : 0; int b = m_curr; GLuint& ta = m_texture[a]; GLuint& tb = m_texture[b]; glBindTexture(GL_TEXTURE_2D, tb); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(90.0/100.0*(float)m_i, (m_dir == 0) ? 1.0 : 0.0, (m_dir == 1) ? 1.0 : 0.0, 0.0); glBindTexture(GL_TEXTURE_2D, ta); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); m_i++; } void SlideShowGL::effectInOut() { if (m_i > 100) { paintTexture(); m_effectRunning = false; m_timeout = -1; return; } if (m_i == 0) { m_dir = 1 + (int)((4.0*rand()/(RAND_MAX+1.0))); } int a; bool out; if (m_i <= 50) { a = (m_curr == 0) ? 1 : 0; out = 1; } else { a = m_curr; out = 0; } GLuint& ta = m_texture[a]; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); float t = out ? 1.0/50.0*(50.0-m_i) : 1.0/50.0*(m_i-50.0); glScalef(t, t, 1.0); t = 1.0 - t; glTranslatef((m_dir % 2 == 0) ? ((m_dir == 2)? 1 : -1) * t : 0.0, (m_dir % 2 == 1) ? ((m_dir == 1)? 1 : -1) * t : 0.0, 0.0); glBindTexture(GL_TEXTURE_2D, ta); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); m_i++; } void SlideShowGL::effectSlide() { if (m_i > 100) { paintTexture(); m_effectRunning = false; m_timeout = -1; return; } if (m_i == 0) m_dir = 1 + (int)((4.0*rand()/(RAND_MAX+1.0))); int a = (m_curr == 0) ? 1 : 0; int b = m_curr; GLuint& ta = m_texture[a]; GLuint& tb = m_texture[b]; glBindTexture(GL_TEXTURE_2D, tb); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); float trans = 2.0/100.0*(float)m_i; glTranslatef((m_dir % 2 == 0) ? ((m_dir == 2)? 1 : -1) * trans : 0.0, (m_dir % 2 == 1) ? ((m_dir == 1)? 1 : -1) * trans : 0.0, 0.0); glBindTexture(GL_TEXTURE_2D, ta); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); m_i++; } void SlideShowGL::effectFlutter() { if (m_i > 100) { paintTexture(); m_effectRunning = false; m_timeout = -1; return; } int a = (m_curr == 0) ? 1 : 0; int b = m_curr; GLuint& ta = m_texture[a]; GLuint& tb = m_texture[b]; if (m_i == 0) { for (int x = 0; x<40; x++) { for (int y = 0; y < 40; y++) { m_points[x][y][0] = (float) (x / 20.0f - 1.0f); m_points[x][y][1] = (float) (y / 20.0f - 1.0f); m_points[x][y][2] = (float) sin((x / 20.0f - 1.0f) * 3.141592654*2.0f)/5.0; } } } glBindTexture(GL_TEXTURE_2D, tb); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1, 0); glVertex3f(1.0f, -1.0f, 0); glTexCoord2f(1, 1); glVertex3f(1.0f, 1.0f, 0); glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 0); } glEnd(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); float rotate = 60.0/100.0*(float)m_i; glRotatef(rotate, 1.0f, 0.0f, 0.0f); float scale = 1.0/100.0*(100.0-(float)m_i); glScalef(scale, scale, scale); glTranslatef(1.0/100.0*(float)m_i, 1.0/100.0*(float)m_i, 0.0); glBindTexture(GL_TEXTURE_2D, ta); glBegin(GL_QUADS); { glColor4f(1.0, 1.0, 1.0, 1.0); float float_x, float_y, float_xb, float_yb; int x, y; for (x = 0; x < 39; x++) { for (y = 0; y < 39; y++) { float_x = (float) x / 40.0f; float_y = (float) y / 40.0f; float_xb = (float) (x + 1) / 40.0f; float_yb = (float) (y + 1) / 40.0f; glTexCoord2f(float_x, float_y); glVertex3f(m_points[x][y][0], m_points[x][y][1], m_points[x][y][2]); glTexCoord2f(float_x, float_yb); glVertex3f(m_points[x][y + 1][0], m_points[x][y + 1][1], m_points[x][y + 1][2]); glTexCoord2f(float_xb, float_yb); glVertex3f(m_points[x + 1][y + 1][0], m_points[x + 1][y + 1][1], m_points[x + 1][y + 1][2]); glTexCoord2f(float_xb, float_y); glVertex3f(m_points[x + 1][y][0], m_points[x + 1][y][1], m_points[x + 1][y][2]); } } } glEnd(); // wave every two iterations if (m_i%2 == 0) { float hold; int x, y; for (y = 0; y < 40; y++) { hold = m_points[0][y][2]; for (x = 0; x < 39; x++) { m_points[x][y][2] = m_points[x + 1][y][2]; } m_points[39][y][2] = hold; } } m_i++; } void SlideShowGL::effectCube() { int tot = 200; int rotStart = 50; if (m_i > tot) { paintTexture(); m_effectRunning = false; m_timeout = -1; return; } // Enable perspective vision glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); int a = (m_curr == 0) ? 1 : 0; int b = m_curr; GLuint& ta = m_texture[a]; GLuint& tb = m_texture[b]; glMatrixMode(GL_PROJECTION); glLoadIdentity(); float PI = 4.0 * atan(1.0); float znear = 3.0; float theta = 2.0 * atan2((float)2.0/(float)2.0, (float)znear); theta = theta * 180.0/PI; glFrustum(-1.0,1.0,-1.0,1.0, znear-0.01,10.0); static float xrot; static float yrot; static float zrot; if (m_i == 0) { xrot = 0.0; yrot = 0.0; zrot = 0.0; } glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); float trans = 5.0 * (float)((m_i <= tot/2) ? m_i : tot-m_i)/(float)tot; glTranslatef(0.0,0.0, -znear - 1.0 - trans); glRotatef(xrot, 1.0f, 0.0f, 0.0f); glRotatef(yrot, 0.0f, 1.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, 0); glBegin(GL_QUADS); { glColor4f(0.0f, 0.0f, 0.0f, 1.0f); /* Front Face */ glVertex3f( -1.00f, -1.00f, 0.99f ); glVertex3f( 1.00f, -1.00f, 0.99f ); glVertex3f( 1.00f, 1.00f, 0.99f ); glVertex3f( -1.00f, 1.00f, 0.99f ); /* Back Face */ glVertex3f( -1.00f, -1.00f, -0.99f ); glVertex3f( -1.00f, 1.00f, -0.99f ); glVertex3f( 1.00f, 1.00f, -0.99f ); glVertex3f( 1.00f, -1.00f, -0.99f ); /* Top Face */ glVertex3f( -1.00f, 0.99f, -1.00f ); glVertex3f( -1.00f, 0.99f, 1.00f ); glVertex3f( 1.00f, 0.99f, 1.00f ); glVertex3f( 1.00f, 0.99f, -1.00f ); /* Bottom Face */ glVertex3f( -1.00f, -0.99f, -1.00f ); glVertex3f( 1.00f, -0.99f, -1.00f ); glVertex3f( 1.00f, -0.99f, 1.00f ); glVertex3f( -1.00f, -0.99f, 1.00f ); /* Right face */ glVertex3f( 0.99f, -1.00f, -1.00f ); glVertex3f( 0.99f, 1.00f, -1.00f ); glVertex3f( 0.99f, 1.00f, 1.00f ); glVertex3f( 0.99f, -1.00f, 1.00f ); /* Left Face */ glVertex3f( -0.99f, -1.00f, -1.00f ); glVertex3f( -0.99f, -1.00f, 1.00f ); glVertex3f( -0.99f, 1.00f, 1.00f ); glVertex3f( -0.99f, 1.00f, -1.00f ); } glEnd(); glBindTexture(GL_TEXTURE_2D, ta); glBegin(GL_QUADS); { glColor4d(1.0, 1.0, 1.0, 1.0); // Front Face glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, 1.00f ); glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f, -1.0f, 1.00f ); glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, 1.0f, 1.00f ); glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f, 1.0f, 1.00f ); // Top Face glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.0f, 1.00f, -1.0f ); glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.0f, 1.00f, 1.0f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.0f, 1.00f, 1.0f ); glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.0f, 1.00f, -1.0f ); // Bottom Face glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f, -1.00f, -1.0f ); glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, -1.00f, -1.0f ); glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f, -1.00f, 1.0f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, -1.00f, 1.0f ); // Right face glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.00f, -1.0f, -1.0f ); glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.00f, -1.0f, 1.0f ); glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.00f, 1.0f, 1.0f ); glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.00f, 1.0f, -1.0f ); // Left Face glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.00f, -1.0f, -1.0f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.00f, 1.0f, -1.0f ); glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.00f, 1.0f, 1.0f ); glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.00f, -1.0f, 1.0f ); } glEnd(); glBindTexture(GL_TEXTURE_2D, tb); glBegin(GL_QUADS); { glColor4d(1.0, 1.0, 1.0, 1.0); // Back Face glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, -1.00f ); glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.0f, 1.0f, -1.00f ); glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.0f, 1.0f, -1.00f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.0f, -1.0f, -1.00f ); } glEnd(); if (m_i >= rotStart && m_i < (tot-rotStart)) { xrot += 360.0f/(float)(tot-2*rotStart); yrot += 180.0f/(float)(tot-2*rotStart); } m_i++; } void SlideShowGL::slotPause() { m_timer->stop(); if (m_toolBar->isHidden()) { int w = m_toolBar->width(); m_toolBar->move(m_deskWidth-w-1,0); m_toolBar->show(); } } void SlideShowGL::slotPlay() { m_toolBar->hide(); slotTimeOut(); } void SlideShowGL::slotPrev() { previousFrame(); if (m_endOfShow) { updateGL(); return; } m_effectRunning = false; loadImage(); updateGL(); } void SlideShowGL::slotNext() { advanceFrame(); if (m_endOfShow) { updateGL(); return; } m_effectRunning = false; loadImage(); updateGL(); } void SlideShowGL::slotClose() { close(); } } // NameSpace KIPISlideShowPlugin #include "slideshowgl.moc"