You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kipi-plugins/kipi-plugins/slideshow/slideshowgl.cpp

1509 lines
37 KiB

/* ============================================================
* File : slideshowgl.cpp
* Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
* Date : 2004-01-19
* Description :
*
* Copyright 2004 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
* Copyright 2007 by Valerio Fuoglio <valerio.fuoglio@gmail.com>
*
* 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 <tdeconfig.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <tdeversion.h>
#include <tdeglobalsettings.h>
#include <kimageeffect.h>
#include <tqtimer.h>
#include <tqpixmap.h>
#include <tqapplication.h>
#include <tqevent.h>
#include <tqcursor.h>
#include <tqimage.h>
#include <tqpainter.h>
#include <tqfileinfo.h>
#include <tqfontmetrics.h>
#include <tqwmatrix.h>
#include <math.h>
#include <cstdlib>
#include "slideshowgl.h"
#include "toolbar.h"
namespace KIPISlideShowPlugin
{
SlideShowGL::SlideShowGL(const TQValueList<TQPair<TQString, int> >& 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() == TQt::LeftButton)
{
m_timer->stop();
m_toolBar->setPaused(true);
slotNext();
}
else if (e->button() == TQt::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<TQString,TQString> SlideShowGL::effectNamesI18N()
{
TQMap<TQString,TQString> 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<TQString,EffectMethod> 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(),
TQImage::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"