All pastes #221820 Raw Edit

Stuff

public cpp v1 · immutable
#221820 ·published 2006-10-25 22:03 UTC
rendered paste body
/* ============================================================ * File  : glsingleview.cpp * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu> * Date  : 2004-01-13 * Description : * * Copyright 2004 by Renchi Raju * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published bythe 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 <iostream>#include <math.h>#include <unistd.h>#include <qsqldatabase.h>#include <qtimer.h>#include <qimage.h>#include <qlayout.h>#include <qsize.h>#include <qfileinfo.h>#include <qdir.h>#include <mythtv/mythcontext.h>#include "glsingleview.h"#include <X11/Xlib.h>#if 1#define glError() for(unsigned long err = glGetError(); err; err = glGetError()) { fprintf(stderr, "glError: %s caught at %s:%u\n", (char*)gluErrorString(err), __FILE__, __LINE__); } #else#define glError() #endif#define GL_ARB_texture_rectangle 1#define CR_LF "\n"GLSDialog::GLSDialog(QSqlDatabase *db, const ThumbList& itemList,                     int pos, bool slideShow, MythMainWindow *parent,                     const char *name)    : MythDialog(parent, name){    QBoxLayout *l = new QVBoxLayout(this);    m_view = new GLSingleView(db, itemList, pos, slideShow, this);    l->addWidget(m_view);    setFocusProxy(m_view);    m_view->setFocus();}// Have to clean up with this dirty hack because// qglwidget segfaults with a destructive closevoid GLSDialog::closeEvent(QCloseEvent *e){    while(m_view->loadingImage)        usleep(100);    m_view->cleanUp();    e->accept();}GLSingleView::GLSingleView(QSqlDatabase *db, ThumbList itemList,                           int pos, bool slideShow, QWidget *parent)    : QGLWidget(parent){    loadingImage = false;    m_db       = db;    m_pos      = pos;    m_itemList = itemList;    // --------------------------------------------------------------------    setFocusPolicy(QWidget::WheelFocus);    int   xbase, ybase;    gContext->GetScreenSettings(xbase, screenwidth, wmult,                                ybase, screenheight, hmult);    m_w = QMIN( 1024, 1 << (int)ceil(log((float)screenwidth)/log((float)2)) );    m_h = QMIN( 1024, 1 << (int)ceil(log((float)screenheight)/log((float)2)) );        // --------------------------------------------------------------------    // remove all dirs from m_itemList;    m_itemList.setAutoDelete(false);    ThumbItem* item = m_itemList.first();    while (item) {        ThumbItem* next = m_itemList.next();        if (item->isDir)            m_itemList.remove(item);        item = next;    }    // since we remove dirs item position might have changed    item = itemList.at(m_pos);    if (item)        m_pos = m_itemList.find(item);    if (!item || (m_pos == -1))        m_pos = 0;    // --------------------------------------------------------------------    m_curr           = 0;    m_texItem[0].tex = 0;    m_texItem[1].tex = 0;    m_tex1First      = true;    // --------------------------------------------------------------------    m_sx = m_sy = 0;    m_zoom = 1.0;    // --------------------------------------------------------------------        // get screen aspect    Display  *display;    display = XOpenDisplay(NULL);    int scr = DefaultScreen(display);    int s_height_mm = DisplayHeightMM(display,scr);    int s_width_mm = DisplayWidthMM(display,scr);    int s_height_px = DisplayHeight(display,scr);    int s_width_px = DisplayWidth(display,scr);    XCloseDisplay(display);    aspect_h = (double)s_height_px/(double)s_height_mm;    aspect_w = (double)s_width_px/(double)s_width_mm;        // ---------------------------------------------------------------    registerEffects();    m_effectMethod = 0;    m_effectRandom = false;    QString transType = gContext->GetSetting("SlideshowOpenGLTransition");    if (!transType.isEmpty() && m_effectMap.contains(transType))        m_effectMethod = m_effectMap[transType];    if (!m_effectMethod || transType == QString("random (gl)")) {        m_effectMethod = getRandomEffect();        m_effectRandom = true;    }    // --------------------------------------------------------------------    m_delay = gContext->GetNumSetting("SlideshowDelay", 0);    if (!m_delay)        m_delay = 2;    // ---------------------------------------------------------------    m_tmout         = m_delay * 1000;    m_effectRunning = false;    m_running       = false;    m_texInfo       = 0;    m_showInfo      = false;    // ---------------------------------------------------------------    m_timer = new QTimer(this);    connect(m_timer, SIGNAL(timeout()),            SLOT(slotTimeOut()));    if (slideShow) {        m_running = true;        m_timer->start(m_tmout, true);    }}GLSingleView::~GLSingleView(){}void GLSingleView::cleanUp(){    makeCurrent();    m_timer->stop();//    delete m_timer;    if (m_texItem[0].tex)        glDeleteTextures(1, &m_texItem[0].tex);    if (m_texItem[1].tex)        glDeleteTextures(1, &m_texItem[1].tex);}void GLSingleView::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);    glEnable(GL_TEXTURE_RECTANGLE_ARB);    // Blending Function For Translucency Based On Source Alpha Value    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);    // Enable perspective vision    glClearDepth(1.0f);    loadImage();        char *extension = strtok((char*)glGetString(GL_EXTENSIONS), " ");    fprintf(stdout, "Vendor Name\t\t\t%s%sVersion\t\t\t\t%s%sGL Shading Language Version\t%s%sRenderer Name\t\t\t%s%sOpenGL Extensions%s\t\t\t\t%s%s", glGetString(GL_VENDOR), CR_LF, glGetString(GL_VERSION), CR_LF, glGetString(GL_SHADING_LANGUAGE_VERSION), CR_LF, glGetString(GL_RENDERER), CR_LF, CR_LF, extension, CR_LF);}void GLSingleView::resizeGL( int w, int h ){    // Reset The Current Viewport And Perspective Transformation    glViewport(0, 0, (GLint)w, (GLint)h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();}void GLSingleView::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_effectRunning && m_effectMethod) {        (this->*m_effectMethod)();    }    else        paintTexture();    if (glGetError())        std::cout << "Oops! I screwed up my OpenGL calls somewhere"                  << std::endl;}void GLSingleView::keyPressEvent(QKeyEvent *e){    bool handled    = false;    bool wasRunning = m_running;    //m_timer->stop();    //m_running = false;    //m_effectRunning = false;    m_tmout = m_delay * 1000;    bool wasInfo = m_showInfo;    m_showInfo = false;    QStringList actions;    gContext->GetMainWindow()->TranslateKeyPress("Gallery", e, actions);    float scrollX = 0.02;    float scrollY = 0.02;    for (unsigned int i = 0; i < actions.size() && !handled; i++)    {        QString action = actions[i];        handled = true;        if (action == "LEFT" || action == "UP")        {            m_zoom = 1.0;            m_sx   = 0;            m_sy   = 0;            retreatFrame();            loadImage();        }        else if (action == "PAUSE")        {            wasRunning = m_running;            m_timer->stop();            printf("STOP TIMER!\n");            m_running = false;            m_effectRunning = false;        }        else if (action == "RIGHT" || action == "DOWN")        {            m_zoom = 1.0;            m_sx   = 0;            m_sy   = 0;            advanceFrame();            loadImage();        }        else if (action == "ZOOMOUT")        {            m_sx   = 0;            m_sy   = 0;            if (m_zoom > 0.5) {                m_zoom = m_zoom /2;            }            else                handled = false;        }        else if (action == "ZOOMIN")        {            m_sx   = 0;            m_sy   = 0;            if (m_zoom < 4.0) {                m_zoom = m_zoom * 2;            }            else                handled = false;        }        else if (action == "FULLSIZE")        {            m_sx = 0;            m_sy = 0;            if (m_zoom != 1) {                m_zoom = 1.0;            }            else                handled = false;        }        else if (action == "SCROLLLEFT")        {            if (m_zoom > 1.0 && m_sx < 1.0) {                m_sx += scrollX;                m_sx  = QMIN(m_sx, 1.0);            }            else                handled = false;        }        else if (action == "SCROLLRIGHT")        {            if (m_zoom > 1.0 && m_sx > -1.0) {                m_sx -= scrollX;                m_sx  = QMAX(m_sx, -1.0);            }            else                handled = false;        }        else if (action == "SCROLLUP")        {            if (m_zoom > 1.0 && m_sy < 1.0) {                m_sy += scrollY;                m_sy  = QMIN(m_sy, 1.0);            }            else                handled = false;        }        else if (action == "SCROLLDOWN")        {            if (m_zoom > 1.0 && m_sy > -1.0) {                m_sy -= scrollY;                m_sy  = QMAX(m_sy, -1.0);            }            else                handled = false;        }        else if (action == "RECENTER")        {            if (m_zoom > 1.0) {                m_sx = 0.0;                m_sy = 0.0;            }            else                handled = false;        }        else if (action == "UPLEFT")        {            if (m_zoom > 1.0) {                m_sx  =  1.0;                m_sy  = -1.0;            }            else                handled = false;        }        else if (action == "LOWRIGHT")        {            if (m_zoom > 1.0) {                m_sx = -1.0;                m_sy =  1.0;            }            else                handled = false;        }        else if (action == "ROTRIGHT")        {            m_sx = 0;            m_sy = 0;            rotate(90);        }        else if (action == "ROTLEFT")        {            m_sx = 0;            m_sy = 0;            rotate(-90);        }        else if (action == "PLAY")        {            m_sx   = 0;            m_sy   = 0;            m_zoom = 1.0;            m_running = !wasRunning;        }        else if (action == "INFO")        {            m_showInfo = !wasInfo;        }        else            handled = false;    }    if (m_running) {        m_timer->start(m_tmout, true);    }    if (handled) {        updateGL();        e->accept();    }    else {        e->ignore();    }}void GLSingleView::paintTexture(){    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    glTranslatef(m_sx, m_sy, 0.0);    glScalef(m_zoom, m_zoom, 1.0);    TexItem& t = m_texItem[m_curr];    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(t.angle, 0.0, 0.0, 1.0);#ifdef GL_ARB_texture_rectangle    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, t.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0);        glTexCoord2f(0, 0);        glVertex2f(-t.cx, -t.cy);        glTexCoord2f(t.width, 0);        glVertex2f(t.cx, -t.cy);            glTexCoord2f(t.width, t.height);        glVertex2f(t.cx, t.cy);        glTexCoord2f(0, t.height);        glVertex2f(-t.cx, t.cy);    }    glEnd();    #else    glBindTexture(GL_TEXTURE_2D, t.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0);        glTexCoord2f(0, 0);        glVertex3f(-t.cx, -t.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(t.cx, -t.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(t.cx, t.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-t.cx, t.cy, 0);    }    glEnd();#endif    if (m_showInfo) {        createTexInfo();        glMatrixMode(GL_MODELVIEW);        glLoadIdentity();        glMatrixMode(GL_TEXTURE);        glLoadIdentity();        glBindTexture(GL_TEXTURE_2D, m_texInfo);        glBegin(GL_QUADS);        {            glColor4f(1.0, 1.0, 1.0, 0.72);            glTexCoord2f(0, 0);            glVertex3f(-0.75, -0.75, 0);            glTexCoord2f(1, 0);            glVertex3f(0.75, -0.75, 0);            glTexCoord2f(1, 1);            glVertex3f(0.75, 0.75, 0);            glTexCoord2f(0, 1);            glVertex3f(-0.75, 0.75, 0);        }        glEnd();    }}void GLSingleView::advanceFrame(){    m_pos++;    if (m_pos >= (int)m_itemList.count())        m_pos = 0;    m_tex1First = !m_tex1First;    m_curr      = (m_curr == 0) ? 1 : 0;}void GLSingleView::retreatFrame(){    m_pos--;    if (m_pos < 0)        m_pos = m_itemList.count() - 1;    m_tex1First = !m_tex1First;    m_curr = (m_curr == 0) ? 1 : 0;}void GLSingleView::loadImage(){    loadingImage = true;    ThumbItem *item = m_itemList.at(m_pos);    if (!item) {        std::cerr << "GLSingleView: The impossible happened. No item at "                  << m_pos << std::endl;        return;    }    QImage image(item->path);    if (!image.isNull()) {        double scale_factor_w =  aspect_w / aspect_h;        int a  = m_tex1First ? 0 : 1;        TexItem& t = m_texItem[a];        t.item     = item;        t.angle    = 0;        QString queryStr = "SELECT angle FROM gallerymetadata WHERE "                           "image=\"" + item->path + "\";";        QSqlQuery query = m_db->exec(queryStr);        if (query.isActive()  && query.numRowsAffected() > 0)        {            query.next();            t.angle = query.value(0).toInt();        }        t.width  = (int)round(image.width() * scale_factor_w);        t.height = (int)round(image.height());        if (t.angle%180 != 0) {            int tmp  = t.width;            t.width  = t.height;            t.height = tmp;        }        QSize sz(t.width,t.height);        sz.scale(screenwidth, screenheight, QSize::ScaleMin);        t.cx = (float)sz.width()/(float)screenwidth;        t.cy = (float)sz.height()/(float)screenheight;        //image = image.smoothScale(m_w, m_h);        QImage tex = convertToGLFormat(image);        /*if (t.tex) {            glDeleteTextures(1, &t.tex);    }*/        /* create the texture */        if(!t.tex)        {            printf("Create texture\n");            glGenTextures(1, &t.tex);        }        glMatrixMode(GL_TEXTURE);        #ifdef GL_ARB_texture_rectangle        glBindTexture(GL_TEXTURE_RECTANGLE_ARB, t.tex);        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);        glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);        glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,                      0, 3, tex.width(), tex.height(), 0,                     GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());                glTexImage2D(GL_PROXY_TEXTURE_RECTANGLE_ARB,                      0,                      GL_RGBA8,                      tex.width(),                      tex.height(),                      0,                      GL_BGRA,                      GL_UNSIGNED_INT_8_8_8_8, 0);                GLint _width, _height;        glGetTexLevelParameteriv(GL_PROXY_TEXTURE_RECTANGLE_ARB, 0, GL_TEXTURE_WIDTH,  &_width);        glGetTexLevelParameteriv(GL_PROXY_TEXTURE_RECTANGLE_ARB, 0, GL_TEXTURE_HEIGHT, &_height);        printf("w: %d, h: %d\n", (int)_width, (int)_height);                GLint r[2];        glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, r);        fprintf(stderr, "%-48s%d\n", "GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB", (int)r[0]);                if(_width && _height)        {            glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,                          0,                          GL_RGBA8,                          tex.width(),                          tex.height(),                          0,                          GL_BGRA,                          GL_UNSIGNED_INT_8_8_8_8,                          tex.bits());            glError();        }        else        {            fprintf(stderr, "...\n");                            exit(1);        }#else        glBindTexture(GL_TEXTURE_2D, t.tex);        /* actually generate the texture */        glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,                      GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );        /* enable linear filtering  */        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);#endif        glFinish();        glError();    }    loadingImage = false;}void GLSingleView::rotate(int angle){    int& ang = m_texItem[m_curr].angle;    ang += angle;    if (ang >= 360)        ang -= 360;    if (ang < 0)        ang += 360;    ThumbItem *item = m_itemList.at(m_pos);    if (item) {        QString queryStr = "REPLACE INTO gallerymetadata SET image=\"" +                           item->path + "\", angle=" +                           QString::number(ang) + ";";        m_db->exec(queryStr);        // Delete thumbnail for this        if (item->pixmap)            delete item->pixmap;        item->pixmap = 0;    }    TexItem& t = m_texItem[m_curr];    int tmp  = t.width;    t.width  = t.height;    t.height = tmp;    QSize sz(t.width,t.height);    sz.scale(screenwidth, screenheight, QSize::ScaleMin);    t.cx = (float)sz.width()/(float)screenwidth;    t.cy = (float)sz.height()/(float)screenheight;}void GLSingleView::registerEffects(){    m_effectMap.insert("none", &GLSingleView::effectNone);    m_effectMap.insert("blend (gl)", &GLSingleView::effectBlend);    m_effectMap.insert("fade (gl)", &GLSingleView::effectFade);    m_effectMap.insert("rotate (gl)", &GLSingleView::effectRotate);    m_effectMap.insert("bend (gl)", &GLSingleView::effectBend);    m_effectMap.insert("inout (gl)", &GLSingleView::effectInOut);    m_effectMap.insert("slide (gl)", &GLSingleView::effectSlide);    m_effectMap.insert("flutter (gl)", &GLSingleView::effectFlutter);    m_effectMap.insert("cube (gl)", &GLSingleView::effectCube);}GLSingleView::EffectMethod GLSingleView::getRandomEffect(){    QMap<QString,EffectMethod>  tmpMap(m_effectMap);    tmpMap.remove("none");    QStringList t = tmpMap.keys();    int count = t.count();    int i = (int)((float)(count)*rand()/(RAND_MAX+1.0));    QString key = t[i];    return tmpMap[key];}void GLSingleView::effectNone(){    paintTexture();    m_effectRunning = false;    m_tmout = -1;    return;}void GLSingleView::effectBlend(){    if (m_i > 50) {        paintTexture();        m_effectRunning = false;        m_tmout = -1;        return;    }    int a = (m_curr == 0) ? 1 : 0;    int b =  m_curr;    TexItem& ta = m_texItem[a];    TexItem& tb = m_texItem[b];    /*    GLuint *textures = (GLuint*)malloc(2*sizeof(GLuint));    textures[0] = ta.tex;    textures[1] = tb.tex;    GLboolean *resid = (GLboolean*)malloc(2*sizeof(GLboolean));    memset(resid, 0, 2*sizeof(GLboolean));    glAreTexturesResident(2, textures, resid);        printf("ta: %d\ntb: %d\n", (uint)resid[0], (uint)resid[1]);        */    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(ta.angle, 0.0, 0.0, 1.0);#ifdef GL_ARB_texture_rectangle    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ta.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0/(50.0)*(float)(50-m_i));        glTexCoord2f(0, 0);        glVertex2f(-ta.cx, -ta.cy);        glTexCoord2f(ta.width, 0);        glVertex2f(ta.cx, -ta.cy);            glTexCoord2f(ta.width, ta.height);        glVertex2f(ta.cx, ta.cy);        glTexCoord2f(0, ta.height);        glVertex2f(-ta.cx, ta.cy);    }    glEnd();    #else    glBindTexture(GL_TEXTURE_2D, ta.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0/(50.0)*(float)(50-m_i));        glTexCoord2f(0, 0);        glVertex3f(-ta.cx, -ta.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(ta.cx, -ta.cy, 0);            glTexCoord2f(1, 1);        glVertex3f(ta.cx, ta.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-ta.cx, ta.cy, 0);    }    glEnd();#endif    glError();    /*glBegin(GL_QUADS);    {        glColor4f(0.0, 0.0, 0.0, 1.0/(100.0)*(float)m_i);        glVertex3f(-1, -1, 0);        glVertex3f(1, -1, 0);        glVertex3f(1, 1, 0);        glVertex3f(-1, 1, 0);    }    glEnd();*/    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(tb.angle, 0.0, 0.0, 1.0);#ifdef GL_ARB_texture_rectangle    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tb.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0/(50.0)*(float)m_i);        glTexCoord2f(0, 0);        glVertex2f(-tb.cx, -tb.cy);        glTexCoord2f(tb.width, 0);        glVertex2f(tb.cx, -tb.cy);            glTexCoord2f(tb.width, tb.height);        glVertex2f(tb.cx, tb.cy);        glTexCoord2f(0, tb.height);        glVertex2f(-tb.cx, tb.cy);    }    glEnd();    #else    glBindTexture(GL_TEXTURE_2D, tb.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0/(50.0)*(float)m_i);        glTexCoord2f(0, 0);        glVertex3f(-tb.cx, -tb.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(tb.cx, -tb.cy, 0);            glTexCoord2f(1, 1);        glVertex3f(tb.cx, tb.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-tb.cx, tb.cy, 0);    }    glEnd();#endif    m_i++;}void GLSingleView::effectRotate(){    if (m_i > 100) {        paintTexture();        m_effectRunning = false;        m_tmout = -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;    TexItem& ta = m_texItem[a];    TexItem& tb = m_texItem[b];    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(tb.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, tb.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0);        glTexCoord2f(0, 0);        glVertex3f(-tb.cx, -tb.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(tb.cx, -tb.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(tb.cx, tb.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-tb.cx, tb.cy, 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);    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(ta.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, ta.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0);        glTexCoord2f(0, 0);        glVertex3f(-ta.cx, -ta.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(ta.cx, -ta.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(ta.cx, ta.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-ta.cx, ta.cy, 0);    }    glEnd();    m_i++;}void GLSingleView::effectBend(){    if (m_i > 100) {        paintTexture();        m_effectRunning = false;        m_tmout = -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;    TexItem& ta = m_texItem[a];    TexItem& tb = m_texItem[b];    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(tb.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, tb.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0);        glTexCoord2f(0, 0);        glVertex3f(-tb.cx, -tb.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(tb.cx, -tb.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(tb.cx, tb.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-tb.cx, tb.cy, 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);    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(ta.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, ta.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0);        glTexCoord2f(0, 0);        glVertex3f(-ta.cx, -ta.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(ta.cx, -ta.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(ta.cx, ta.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-ta.cx, ta.cy, 0);    }    glEnd();    m_i++;}void GLSingleView::effectFade(){    if (m_i > 100) {        paintTexture();        m_effectRunning = false;        m_tmout = -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;    }    TexItem& ta = m_texItem[a];    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(ta.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, ta.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, opacity);        glTexCoord2f(0, 0);        glVertex3f(-ta.cx, -ta.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(ta.cx, -ta.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(ta.cx, ta.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-ta.cx, ta.cy, 0);    }    glEnd();    m_i++;}void GLSingleView::effectInOut(){    if (m_i > 100) {        paintTexture();        m_effectRunning = false;        m_tmout = -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;    }    TexItem& ta = m_texItem[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);    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(ta.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, ta.tex);    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(-ta.cx, -ta.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(ta.cx, -ta.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(ta.cx, ta.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-ta.cx, ta.cy, 0);    }    glEnd();    m_i++;}void GLSingleView::effectSlide(){    if (m_i > 100) {        paintTexture();        m_effectRunning = false;        m_tmout = -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;    TexItem& ta = m_texItem[a];    TexItem& tb = m_texItem[b];    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(tb.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, tb.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0);        glTexCoord2f(0, 0);        glVertex3f(-tb.cx, -tb.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(tb.cx, -tb.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(tb.cx, tb.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-tb.cx, tb.cy, 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);    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(ta.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, ta.tex);    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(-ta.cx, -ta.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(ta.cx, -ta.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(ta.cx, ta.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-ta.cx, ta.cy, 0);    }    glEnd();    m_i++;}void GLSingleView::effectFlutter(){    if (m_i > 100) {        paintTexture();        m_effectRunning = false;        m_tmout = -1;        return;    }    int a = (m_curr == 0) ? 1 : 0;    int b =  m_curr;    TexItem& ta = m_texItem[a];    TexItem& tb = m_texItem[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) * ta.cx;                m_points[x][y][1] = (float) (y / 20.0f - 1.0f) * ta.cy;                m_points[x][y][2] = (float) sin((x / 20.0f - 1.0f) * 3.141592654*2.0f)/5.0;            }        }    }    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(tb.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, tb.tex);    glBegin(GL_QUADS);    {        glColor4f(1.0, 1.0, 1.0, 1.0);        glTexCoord2f(0, 0);        glVertex3f(-tb.cx, -tb.cy, 0);        glTexCoord2f(1, 0);        glVertex3f(tb.cx, -tb.cy, 0);        glTexCoord2f(1, 1);        glVertex3f(tb.cx, tb.cy, 0);        glTexCoord2f(0, 1);        glVertex3f(-tb.cx, tb.cy, 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);    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(ta.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, ta.tex);    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 GLSingleView::effectCube(){    int tot = 200;    int rotStart = 50;    if (m_i > tot) {        paintTexture();        m_effectRunning = false;        m_tmout = -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;    TexItem& ta = m_texItem[a];    TexItem& tb = m_texItem[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();    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(ta.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, ta.tex);    glBegin(GL_QUADS);    {        glColor4d(1.0, 1.0, 1.0, 1.0);        // Front Face        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -ta.cx, -ta.cy,  1.00f );        glTexCoord2f( 1.0f, 0.0f ); glVertex3f(  ta.cx, -ta.cy,  1.00f );        glTexCoord2f( 1.0f, 1.0f ); glVertex3f(  ta.cx,  ta.cy,  1.00f );        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -ta.cx,  ta.cy,  1.00f );        // Top Face        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -ta.cx,  1.00f, -ta.cy );        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -ta.cx,  1.00f,  ta.cy );        glTexCoord2f( 0.0f, 0.0f ); glVertex3f(  ta.cx,  1.00f,  ta.cy );        glTexCoord2f( 0.0f, 1.0f ); glVertex3f(  ta.cx,  1.00f, -ta.cy );        // Bottom Face        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -ta.cx, -1.00f, -ta.cy );        glTexCoord2f( 1.0f, 1.0f ); glVertex3f(  ta.cx, -1.00f, -ta.cy );        glTexCoord2f( 1.0f, 0.0f ); glVertex3f(  ta.cx, -1.00f,  ta.cy );        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -ta.cx, -1.00f,  ta.cy );        // Right face        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.00f, -ta.cx, -ta.cy );        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.00f, -ta.cx,  ta.cy );        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.00f,  ta.cx,  ta.cy );        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.00f,  ta.cx, -ta.cy );        // Left Face        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.00f, -ta.cx, -ta.cy );        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.00f,  ta.cx, -ta.cy );        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.00f,  ta.cx,  ta.cy );        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.00f, -ta.cx,  ta.cy );    }    glEnd();    glMatrixMode(GL_TEXTURE);    glLoadIdentity();    glRotatef(tb.angle, 0.0, 0.0, 1.0);    glBindTexture(GL_TEXTURE_2D, tb.tex);    glBegin(GL_QUADS);    {        glColor4d(1.0, 1.0, 1.0, 1.0);        // Back Face        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -tb.cx, -tb.cy, -1.00f );        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -tb.cx,  tb.cy, -1.00f );        glTexCoord2f( 0.0f, 1.0f ); glVertex3f(  tb.cx,  tb.cy, -1.00f );        glTexCoord2f( 0.0f, 0.0f ); glVertex3f(  tb.cx, -tb.cy, -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 GLSingleView::slotTimeOut(){    bool render = true;    if (!m_effectMethod) {        std::cerr << "GLSlideShow: No transition method"                  << std::endl;        return;    }    if (m_effectRunning) {        m_tmout = 20;    }    else {        if (m_tmout == -1) {            // effect was running and is complete now            // run timer while showing current image            m_tmout = m_delay * 1000;            m_i     = 0;            m_timer->stop();        }        else {            // timed out after showing current image            // load next image and start effect            if (m_effectRandom)                m_effectMethod = getRandomEffect();            advanceFrame();            loadImage();            render=false;            m_tmout = 100;            m_effectRunning = true;            m_i = 0;        }    }    if(render)        updateGL();    m_timer->start(m_tmout, true);}void GLSingleView::createTexInfo(){    if (m_texInfo)        glDeleteTextures(1, &m_texInfo);    TexItem& t = m_texItem[m_curr];    if (!t.tex || !t.item)        return;    QPixmap pix(512, 512);    QPainter p(&pix, this);    p.fillRect(0,0,pix.width(),pix.height(),Qt::black);    p.setPen(Qt::white);    QFileInfo fi(t.item->path);    QString info(t.item->name);    info += "\n\n" + tr("Folder: ") + fi.dir().dirName();    info += "\n" + tr("Created: ") + fi.created().toString();    info += "\n" + tr("Modified: ") + fi.lastModified().toString();    info += "\n" + QString(tr("Bytes") + ": %1").arg(fi.size());    info += "\n" + QString(tr("Width") + ": %1 " + tr("pixels"))             .arg(t.width);    info += "\n" + QString(tr("Height") + ": %1 " + tr("pixels"))            .arg(t.height);    info += "\n" + QString(tr("Pixel Count") + ": %1 " +                           tr("megapixels"))            .arg((float) t.width * t.height / 1000000,                 0, 'f', 2);    info += "\n" + QString(tr("Rotation Angle") + ": %1 " +                           tr("degrees")).arg(t.angle);    p.drawText(10, 10, pix.width()-20, pix.height()-20,               Qt::AlignLeft, info);    p.end();    QImage img(pix.convertToImage());    img = img.convertDepth(32);    QImage tex = convertToGLFormat(img);    /* create the texture */    glGenTextures(1, &m_texInfo);    glBindTexture(GL_TEXTURE_2D, m_texInfo);    /* actually generate the texture */    glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,                  GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );    /* enable linear filtering  */    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);}