mirror of
https://github.com/YACReader/yacreader
synced 2025-06-03 09:08:20 -04:00
corregido bug en la gesti?n de eventos de teclado de goToFlow el nombre del fichero de c?mics se muestra ahora en el t?tulo de la ventana de YACReader
1397 lines
35 KiB
C++
1397 lines
35 KiB
C++
#include "yacreader_flow_gl.h"
|
||
|
||
#include <QtGui>
|
||
#include <QtOpenGL>
|
||
#include <math.h>
|
||
#include <gl/GLU.h>
|
||
#include <QGLContext>
|
||
#include <QGLPixelBuffer>
|
||
|
||
/*** Animation Settings ***/
|
||
|
||
/*** Position Configuration ***/
|
||
|
||
struct Preset defaultYACReaderFlowConfig = {
|
||
0.08f, //Animation_step sets the speed of the animation
|
||
1.5f, //Animation_speedup sets the acceleration of the animation
|
||
0.1f, //Animation_step_max sets the maximum speed of the animation
|
||
3.f, //Animation_Fade_out_dis sets the distance of view
|
||
|
||
1.5f, //pre_rotation sets the rotation increasion
|
||
3.f, //View_rotate_light_strenght sets the light strenght on rotation
|
||
0.01f, //View_rotate_add sets the speed of the rotation
|
||
0.02f, //View_rotate_sub sets the speed of reversing the rotation
|
||
20.f, //View_angle sets the maximum view angle
|
||
|
||
0.f, //CF_X the X Position of the Coverflow
|
||
0.f, //CF_Y the Y Position of the Coverflow
|
||
-12.f, //CF_Z the Z Position of the Coverflow
|
||
|
||
15.f, //CF_RX the X Rotation of the Coverflow
|
||
0.f, //CF_RY the Y Rotation of the Coverflow
|
||
0.f, //CF_RZ the Z Rotation of the Coverflow
|
||
|
||
-50.f, //Rotation sets the rotation of each cover
|
||
0.18f, //X_Distance sets the distance between the covers
|
||
1.f, //Center_Distance sets the distance between the centered and the non centered covers
|
||
0.1f, //Z_Distance sets the pushback amount
|
||
0.0f, //Y_Distance sets the elevation amount
|
||
|
||
30.f //zoom level
|
||
|
||
};
|
||
|
||
struct Preset presetYACReaderFlowClassicConfig = {
|
||
0.08f, //Animation_step sets the speed of the animation
|
||
1.5f, //Animation_speedup sets the acceleration of the animation
|
||
0.1f, //Animation_step_max sets the maximum speed of the animation
|
||
2.f, //Animation_Fade_out_dis sets the distance of view
|
||
|
||
1.5f, //pre_rotation sets the rotation increasion
|
||
3.f, //View_rotate_light_strenght sets the light strenght on rotation
|
||
0.08f, //View_rotate_add sets the speed of the rotation
|
||
0.08f, //View_rotate_sub sets the speed of reversing the rotation
|
||
30.f, //View_angle sets the maximum view angle
|
||
|
||
0.f, //CF_X the X Position of the Coverflow
|
||
-0.2f, //CF_Y the Y Position of the Coverflow
|
||
-7.f, //CF_Z the Z Position of the Coverflow
|
||
|
||
0.f, //CF_RX the X Rotation of the Coverflow
|
||
0.f, //CF_RY the Y Rotation of the Coverflow
|
||
0.f, //CF_RZ the Z Rotation of the Coverflow
|
||
|
||
-40.f, //Rotation sets the rotation of each cover
|
||
0.18f, //X_Distance sets the distance between the covers
|
||
1.f, //Center_Distance sets the distance between the centered and the non centered covers
|
||
0.1f, //Z_Distance sets the pushback amount
|
||
0.0f, //Y_Distance sets the elevation amount
|
||
|
||
22.f //zoom level
|
||
|
||
};
|
||
|
||
struct Preset presetYACReaderFlowStripeConfig = {
|
||
0.08f, //Animation_step sets the speed of the animation
|
||
1.5f, //Animation_speedup sets the acceleration of the animation
|
||
0.1f, //Animation_step_max sets the maximum speed of the animation
|
||
6.f, //Animation_Fade_out_dis sets the distance of view
|
||
|
||
1.5f, //pre_rotation sets the rotation increasion
|
||
4.f, //View_rotate_light_strenght sets the light strenght on rotation
|
||
0.08f, //View_rotate_add sets the speed of the rotation
|
||
0.08f, //View_rotate_sub sets the speed of reversing the rotation
|
||
30.f, //View_angle sets the maximum view angle
|
||
|
||
0.f, //CF_X the X Position of the Coverflow
|
||
-0.2f, //CF_Y the Y Position of the Coverflow
|
||
-7.f, //CF_Z the Z Position of the Coverflow
|
||
|
||
0.f, //CF_RX the X Rotation of the Coverflow
|
||
0.f, //CF_RY the Y Rotation of the Coverflow
|
||
0.f, //CF_RZ the Z Rotation of the Coverflow
|
||
|
||
0.f, //Rotation sets the rotation of each cover
|
||
1.1f, //X_Distance sets the distance between the covers
|
||
0.2f, //Center_Distance sets the distance between the centered and the non centered covers
|
||
0.01f, //Z_Distance sets the pushback amount
|
||
0.0f, //Y_Distance sets the elevation amount
|
||
|
||
22.f //zoom level
|
||
|
||
};
|
||
|
||
struct Preset presetYACReaderFlowOverlappedStripeConfig = {
|
||
0.08f, //Animation_step sets the speed of the animation
|
||
1.5f, //Animation_speedup sets the acceleration of the animation
|
||
0.1f, //Animation_step_max sets the maximum speed of the animation
|
||
2.f, //Animation_Fade_out_dis sets the distance of view
|
||
|
||
1.5f, //pre_rotation sets the rotation increasion
|
||
3.f, //View_rotate_light_strenght sets the light strenght on rotation
|
||
0.08f, //View_rotate_add sets the speed of the rotation
|
||
0.08f, //View_rotate_sub sets the speed of reversing the rotation
|
||
30.f, //View_angle sets the maximum view angle
|
||
|
||
0.f, //CF_X the X Position of the Coverflow
|
||
-0.2f, //CF_Y the Y Position of the Coverflow
|
||
-7.f, //CF_Z the Z Position of the Coverflow
|
||
|
||
0.f, //CF_RX the X Rotation of the Coverflow
|
||
0.f, //CF_RY the Y Rotation of the Coverflow
|
||
0.f, //CF_RZ the Z Rotation of the Coverflow
|
||
|
||
0.f, //Rotation sets the rotation of each cover
|
||
0.18f, //X_Distance sets the distance between the covers
|
||
1.f, //Center_Distance sets the distance between the centered and the non centered covers
|
||
0.1f, //Z_Distance sets the pushback amount
|
||
0.0f, //Y_Distance sets the elevation amount
|
||
|
||
22.f //zoom level
|
||
|
||
};
|
||
|
||
struct Preset pressetYACReaderFlowUpConfig = {
|
||
0.08f, //Animation_step sets the speed of the animation
|
||
1.5f, //Animation_speedup sets the acceleration of the animation
|
||
0.1f, //Animation_step_max sets the maximum speed of the animation
|
||
2.5f, //Animation_Fade_out_dis sets the distance of view
|
||
|
||
1.5f, //pre_rotation sets the rotation increasion
|
||
3.f, //View_rotate_light_strenght sets the light strenght on rotation
|
||
0.08f, //View_rotate_add sets the speed of the rotation
|
||
0.08f, //View_rotate_sub sets the speed of reversing the rotation
|
||
5.f, //View_angle sets the maximum view angle
|
||
|
||
0.f, //CF_X the X Position of the Coverflow
|
||
-0.2f, //CF_Y the Y Position of the Coverflow
|
||
-7.f, //CF_Z the Z Position of the Coverflow
|
||
|
||
0.f, //CF_RX the X Rotation of the Coverflow
|
||
0.f, //CF_RY the Y Rotation of the Coverflow
|
||
0.f, //CF_RZ the Z Rotation of the Coverflow
|
||
|
||
-50.f, //Rotation sets the rotation of each cover
|
||
0.18f, //X_Distance sets the distance between the covers
|
||
1.f, //Center_Distance sets the distance between the centered and the non centered covers
|
||
0.1f, //Z_Distance sets the pushback amount
|
||
-0.1f, //Y_Distance sets the elevation amount
|
||
|
||
22.f //zoom level
|
||
|
||
};
|
||
|
||
struct Preset pressetYACReaderFlowDownConfig = {
|
||
0.08f, //Animation_step sets the speed of the animation
|
||
1.5f, //Animation_speedup sets the acceleration of the animation
|
||
0.1f, //Animation_step_max sets the maximum speed of the animation
|
||
2.5f, //Animation_Fade_out_dis sets the distance of view
|
||
|
||
1.5f, //pre_rotation sets the rotation increasion
|
||
3.f, //View_rotate_light_strenght sets the light strenght on rotation
|
||
0.08f, //View_rotate_add sets the speed of the rotation
|
||
0.08f, //View_rotate_sub sets the speed of reversing the rotation
|
||
5.f, //View_angle sets the maximum view angle
|
||
|
||
0.f, //CF_X the X Position of the Coverflow
|
||
-0.2f, //CF_Y the Y Position of the Coverflow
|
||
-7.f, //CF_Z the Z Position of the Coverflow
|
||
|
||
0.f, //CF_RX the X Rotation of the Coverflow
|
||
0.f, //CF_RY the Y Rotation of the Coverflow
|
||
0.f, //CF_RZ the Z Rotation of the Coverflow
|
||
|
||
-50.f, //Rotation sets the rotation of each cover
|
||
0.18f, //X_Distance sets the distance between the covers
|
||
1.f, //Center_Distance sets the distance between the centered and the non centered covers
|
||
0.1f, //Z_Distance sets the pushback amount
|
||
0.1f, //Y_Distance sets the elevation amount
|
||
|
||
22.f //zoom level
|
||
};
|
||
/*Constructor*/
|
||
YACReaderFlowGL::YACReaderFlowGL(QWidget *parent,struct Preset p)
|
||
:QGLWidget(QGLFormat(QGL::SampleBuffers), parent),numObjects(0),lazyPopulateObjects(-1),bUseVSync(false)
|
||
{
|
||
updateCount = 0;
|
||
config = p;
|
||
|
||
currentSelected = 0;
|
||
|
||
centerPos.x = 0.f;
|
||
centerPos.y = 0.f;
|
||
centerPos.z = 1.f;
|
||
centerPos.rot = 0.f;
|
||
|
||
/*** Style ***/
|
||
shadingTop = 0.8f;
|
||
shadingBottom = 0.02f;
|
||
reflectionUp = 0.f;
|
||
reflectionBottom = 0.6f;
|
||
|
||
/*** System variables ***/
|
||
numObjects = 0;
|
||
//CFImage Dummy;
|
||
viewRotate = 0.f;
|
||
viewRotateActive = 0;
|
||
stepBackup = config.animationStep/config.animationSpeedUp;
|
||
|
||
/*QTimer * timer = new QTimer();
|
||
connect(timer, SIGNAL(timeout()), this, SLOT(updateImageData()));
|
||
timer->start(70);
|
||
*/
|
||
|
||
/*loader = new WidgetLoader(0,this);
|
||
loader->flow = this;
|
||
QThread * loaderThread = new QThread(parent);
|
||
|
||
loader->moveToThread(loaderThread);
|
||
|
||
loaderThread->start();*/
|
||
timerId = startTimer(16);
|
||
}
|
||
|
||
void YACReaderFlowGL::timerEvent(QTimerEvent * event)
|
||
{
|
||
if(timerId == event->timerId())
|
||
update();
|
||
|
||
//if(!worker->isRunning())
|
||
//worker->start();
|
||
}
|
||
|
||
YACReaderFlowGL::~YACReaderFlowGL()
|
||
{
|
||
|
||
}
|
||
|
||
QSize YACReaderFlowGL::minimumSizeHint() const
|
||
{
|
||
return QSize(800, 480);
|
||
}
|
||
|
||
QSize YACReaderFlowGL::sizeHint() const
|
||
{
|
||
return QSize(800, 480);
|
||
}
|
||
|
||
void YACReaderFlowGL::initializeGL()
|
||
{
|
||
glEnable(GL_DEPTH_TEST);
|
||
glEnable(GL_COLOR_MATERIAL);
|
||
glShadeModel(GL_SMOOTH);
|
||
glEnable(GL_BLEND);
|
||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||
|
||
defaultTexture = bindTexture(QImage(":/images/defaultCover.png"),GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption);
|
||
markTexture = bindTexture(QImage(":/images/setRead.png"),GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption);
|
||
|
||
if(lazyPopulateObjects!=-1)
|
||
populate(lazyPopulateObjects);
|
||
}
|
||
|
||
void YACReaderFlowGL::paintGL()
|
||
{
|
||
/*glClearDepth(1.0);
|
||
glClearColor(1,1,1,1);*/
|
||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||
/*glLoadIdentity();
|
||
glTranslatef(0.0, 0.0, -10.0);
|
||
glPopMatrix();*/
|
||
if(numObjects>0)
|
||
{
|
||
updatePositions();
|
||
draw();
|
||
}
|
||
}
|
||
|
||
void YACReaderFlowGL::resizeGL(int width, int height)
|
||
{
|
||
|
||
fontSize = width * 0.02;
|
||
|
||
//int side = qMin(width, height);
|
||
glViewport(0, 0, width, height);
|
||
|
||
glMatrixMode(GL_PROJECTION);
|
||
glLoadIdentity();
|
||
#ifdef QT_OPENGL_ES_1
|
||
//glOrthof(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
|
||
#else
|
||
//float sideX = ((float(width)/height)/2)*1.5;
|
||
//float sideY = 0.5*1.5;
|
||
gluPerspective(20.0, (float)width / (float)height, 1.0, 200.0);
|
||
//glOrtho(-sideX, sideX, -sideY+0.2, +sideY+0.2, 4, 11.0);
|
||
|
||
#endif
|
||
glMatrixMode(GL_MODELVIEW);
|
||
|
||
if(numObjects>0)
|
||
updatePositions();
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
/*Private*/
|
||
void YACReaderFlowGL::calcPos(CFImage *CF,int pos)
|
||
{
|
||
if(pos == 0){
|
||
CF->current = centerPos;
|
||
}else{
|
||
if(pos > 0){
|
||
CF->current.x = (config.centerDistance)+(config.xDistance*pos);
|
||
CF->current.y = config.yDistance*pos*-1;
|
||
CF->current.z = config.zDistance*pos*-1;
|
||
CF->current.rot = config.rotation;
|
||
}else{
|
||
CF->current.x = (config.centerDistance)*-1+(config.xDistance*pos);
|
||
CF->current.y = config.yDistance*pos;
|
||
CF->current.z = config.zDistance*pos;
|
||
CF->current.rot = config.rotation*-1;
|
||
}
|
||
}
|
||
|
||
}
|
||
void YACReaderFlowGL::calcRV(RVect *RV,int pos)
|
||
{
|
||
calcPos(&dummy,pos);
|
||
|
||
RV->x = dummy.current.x;
|
||
RV->y = dummy.current.y;
|
||
RV->z = dummy.current.z;
|
||
RV->rot = dummy.current.rot;
|
||
|
||
}
|
||
void YACReaderFlowGL::animate(RVect *Current,RVect to)
|
||
{
|
||
//calculate and apply positions
|
||
Current->x = Current->x+(to.x-Current->x)*config.animationStep;
|
||
Current->y = Current->y+(to.y-Current->y)*config.animationStep;
|
||
Current->z = Current->z+(to.z-Current->z)*config.animationStep;
|
||
|
||
if(abs(to.rot-Current->rot) > 0.01){
|
||
Current->rot = Current->rot+(to.rot-Current->rot)*(config.animationStep*config.preRotation);
|
||
}
|
||
else
|
||
viewRotateActive = 0;
|
||
|
||
}
|
||
void YACReaderFlowGL::drawCover(CFImage *CF)
|
||
{
|
||
float w = CF->width;
|
||
float h = CF->height;
|
||
|
||
//fadeout
|
||
float opacity = 1-1/(config.animationFadeOutDist+config.viewRotateLightStrenght*abs(viewRotate))*abs(0-CF->current.x);
|
||
|
||
glLoadIdentity();
|
||
glTranslatef(config.cfX,config.cfY,config.cfZ);
|
||
glRotatef(config.cfRX,1,0,0);
|
||
glRotatef(viewRotate*config.viewAngle+config.cfRY,0,1,0);
|
||
glRotatef(config.cfRZ,0,0,1);
|
||
|
||
glTranslatef( CF->current.x, CF->current.y, CF->current.z );
|
||
|
||
glPushMatrix();
|
||
glRotatef(CF->current.rot,0,1,0);
|
||
|
||
glEnable(GL_TEXTURE_2D);
|
||
glBindTexture(GL_TEXTURE_2D, CF->img);
|
||
|
||
//calculate shading
|
||
float LShading = ((config.rotation != 0 )?((CF->current.rot < 0)?1-1/config.rotation*CF->current.rot:1):1);
|
||
float RShading = ((config.rotation != 0 )?((CF->current.rot > 0)?1-1/(config.rotation*-1)*CF->current.rot:1):1);
|
||
float LUP = shadingTop+(1-shadingTop)*LShading;
|
||
float LDOWN = shadingBottom+(1-shadingBottom)*LShading;
|
||
float RUP = shadingTop+(1-shadingTop)*RShading;
|
||
float RDOWN = shadingBottom+(1-shadingBottom)*RShading;;
|
||
|
||
|
||
//DrawCover
|
||
glBegin(GL_QUADS);
|
||
|
||
//esquina inferior izquierda
|
||
glColor4f(LDOWN*opacity,LDOWN*opacity,LDOWN*opacity,1);
|
||
glTexCoord2f(0.0f, 1.0f);
|
||
glVertex3f(w/2.f*-1.f, -0.5f, 0.f);
|
||
|
||
//esquina inferior derecha
|
||
glColor4f(RDOWN*opacity,RDOWN*opacity,RDOWN*opacity,1);
|
||
glTexCoord2f(1.0f, 1.0f);
|
||
glVertex3f(w/2.f, -0.5f, 0.f);
|
||
|
||
//esquina superior derecha
|
||
glColor4f(RUP*opacity,RUP*opacity,RUP*opacity,1);
|
||
glTexCoord2f(1.0f, 0.0f);
|
||
glVertex3f(w/2.f, -0.5f+h, 0.f);
|
||
|
||
//esquina superior izquierda
|
||
glColor4f(LUP*opacity,LUP*opacity,LUP*opacity,1);
|
||
glTexCoord2f(0.0f, 0.0f);
|
||
glVertex3f(w/2.f*-1.f, -0.5f+h, 0.f);
|
||
|
||
glEnd();
|
||
|
||
|
||
|
||
//Draw reflection
|
||
glBegin(GL_QUADS);
|
||
|
||
//esquina inferior izquierda
|
||
glColor4f(LUP*opacity*reflectionUp,LUP*opacity*reflectionUp,LUP*opacity*reflectionUp,opacity*reflectionUp);
|
||
glTexCoord2f(0.0f, 0.0f);
|
||
glVertex3f(w/2.f*-1.f, -0.5f-h, 0.f);
|
||
|
||
//esquina inferior derecha
|
||
glTexCoord2f(1.0f, 0.0f);
|
||
glVertex3f(w/2.f, -0.5f-h, 0.f);
|
||
|
||
//esquina superior derecha
|
||
glColor4f(opacity*reflectionBottom,opacity*reflectionBottom,opacity*reflectionBottom,opacity*reflectionBottom);
|
||
glTexCoord2f(1.0f, 1.0f);
|
||
glVertex3f(w/2.f, -0.5f, 0.f);
|
||
|
||
//esquina superior izquierda
|
||
glTexCoord2f(0.0f, 1.0f);
|
||
glVertex3f(w/2.f*-1.f, -0.5f, 0.f);
|
||
|
||
glEnd();
|
||
glDisable(GL_TEXTURE_2D);
|
||
|
||
if(showMarks && loaded[CF->index] && marks[CF->index])
|
||
{
|
||
glEnable(GL_TEXTURE_2D);
|
||
glBindTexture(GL_TEXTURE_2D, markTexture);
|
||
glBegin(GL_QUADS);
|
||
|
||
//esquina inferior izquierda
|
||
glColor4f(LDOWN*opacity,LDOWN*opacity,LDOWN*opacity,1);
|
||
glTexCoord2f(0.0f, 1.0f);
|
||
glVertex3f(w/2.f-0.2f, -0.5f, 0.0001f);
|
||
|
||
//esquina inferior derecha
|
||
glColor4f(RDOWN*opacity,RDOWN*opacity,RDOWN*opacity,1);
|
||
glTexCoord2f(1.0f, 1.0f);
|
||
glVertex3f(w/2.f, -0.5f, 0.0001f);
|
||
|
||
//esquina superior derecha
|
||
glColor4f(RUP*opacity,RUP*opacity,RUP*opacity,1);
|
||
glTexCoord2f(1.0f, 0.0f);
|
||
glVertex3f(w/2.f, -0.3f, 0.0001f);
|
||
|
||
//esquina superior izquierda
|
||
glColor4f(LUP*opacity,LUP*opacity,LUP*opacity,1);
|
||
glTexCoord2f(0.0f, 0.0f);
|
||
glVertex3f(w/2.f-0.2f, -0.3f, 0.0001f);
|
||
|
||
glEnd();
|
||
glDisable(GL_TEXTURE_2D);
|
||
}
|
||
|
||
|
||
glPopMatrix();
|
||
}
|
||
|
||
/*Public*/
|
||
void YACReaderFlowGL::cleanupAnimation()
|
||
{
|
||
config.animationStep = stepBackup;
|
||
viewRotateActive = 0;
|
||
}
|
||
|
||
void YACReaderFlowGL::draw()
|
||
{
|
||
int CS = currentSelected;
|
||
int count;
|
||
|
||
|
||
//Draw right Covers
|
||
for(count = numObjects-1;count > -1;count--){
|
||
if(count > CS){
|
||
drawCover(&cfImages[count]);
|
||
}
|
||
}
|
||
|
||
//Draw left Covers
|
||
for(count = 0;count < numObjects-1;count++){
|
||
if(count < CS){
|
||
drawCover(&cfImages[count]);
|
||
}
|
||
}
|
||
|
||
//Draw Center Cover
|
||
drawCover(&cfImages[CS]);
|
||
|
||
//glDisable(GL_DEPTH_TEST);
|
||
glMatrixMode(GL_PROJECTION);
|
||
glPushMatrix();
|
||
glLoadIdentity();
|
||
glOrtho(-(float(width())/height())/2.0,(float(width())/height())/2.0, 0, 1, -10, 10);
|
||
glMatrixMode(GL_MODELVIEW);
|
||
glLoadIdentity();
|
||
|
||
glBegin( GL_TRIANGLES );
|
||
|
||
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
|
||
glVertex2f( -0.03f, 0.98f);
|
||
glVertex2f( 0.03f, 0.98f);
|
||
glVertex2f( 0.f, 0.949f);
|
||
|
||
glEnd();
|
||
|
||
renderText(10, fontSize + 10,QString("%1/%2").arg(currentSelected+1).arg(numObjects),QFont("Arial", fontSize));
|
||
|
||
glEnable(GL_DEPTH_TEST);
|
||
glMatrixMode(GL_PROJECTION);
|
||
glPopMatrix();
|
||
glMatrixMode(GL_MODELVIEW);
|
||
}
|
||
|
||
void YACReaderFlowGL::showPrevious()
|
||
{
|
||
if(currentSelected > 0){
|
||
|
||
currentSelected--;
|
||
emit centerIndexChanged(currentSelected);
|
||
config.animationStep *= config.animationSpeedUp;
|
||
|
||
if(config.animationStep > config.animationStepMax){
|
||
config.animationStep = config.animationStepMax;
|
||
}
|
||
|
||
if(viewRotateActive && viewRotate > -1){
|
||
viewRotate -= config.viewRotateAdd;
|
||
}
|
||
|
||
viewRotateActive = 1;
|
||
|
||
}
|
||
}
|
||
|
||
void YACReaderFlowGL::showNext()
|
||
{
|
||
if(currentSelected < numObjects-1){
|
||
|
||
currentSelected++;
|
||
emit centerIndexChanged(currentSelected);
|
||
config.animationStep *= config.animationSpeedUp;
|
||
|
||
if(config.animationStep > config.animationStepMax){
|
||
config.animationStep = config.animationStepMax;
|
||
}
|
||
|
||
if(viewRotateActive && viewRotate < 1){
|
||
viewRotate += config.viewRotateAdd;
|
||
}
|
||
|
||
viewRotateActive = 1;
|
||
}
|
||
}
|
||
|
||
void YACReaderFlowGL::setCurrentIndex(int pos)
|
||
{
|
||
currentSelected = pos;
|
||
|
||
config.animationStep *= config.animationSpeedUp;
|
||
|
||
if(config.animationStep > config.animationStepMax){
|
||
config.animationStep = config.animationStepMax;
|
||
}
|
||
|
||
if(viewRotateActive && viewRotate < 1){
|
||
viewRotate += config.viewRotateAdd;
|
||
}
|
||
|
||
viewRotateActive = 1;
|
||
}
|
||
|
||
void YACReaderFlowGL::updatePositions()
|
||
{
|
||
int count;
|
||
|
||
for(count = numObjects-1;count > -1;count--){
|
||
calcRV(&cfImages[count].animEnd,count-currentSelected);
|
||
animate(&cfImages[count].current,cfImages[count].animEnd);
|
||
}
|
||
|
||
//slowly reset view angle
|
||
if(!viewRotateActive){
|
||
viewRotate += (0-viewRotate)*config.viewRotateSub;
|
||
}
|
||
|
||
if(abs (cfImages[currentSelected].current.x - cfImages[currentSelected].animEnd.x) < 1)//viewRotate < 0.2)
|
||
{
|
||
cleanupAnimation();
|
||
if(updateCount >= 0) //TODO parametrizar
|
||
{
|
||
|
||
updateCount = 0;
|
||
updateImageData();
|
||
}
|
||
else
|
||
updateCount++;
|
||
}
|
||
else
|
||
updateCount++;
|
||
|
||
}
|
||
|
||
void YACReaderFlowGL::insert(char *name, GLuint Tex, float x, float y,int item)
|
||
{
|
||
//set a new entry
|
||
if(item == -1){
|
||
|
||
if(numObjects == 0){
|
||
cfImages = (CFImage*)malloc(sizeof(CFImage));
|
||
}
|
||
else
|
||
{
|
||
cfImages = (CFImage*)realloc(cfImages,(numObjects+1)*sizeof(CFImage));
|
||
}
|
||
|
||
item = numObjects;
|
||
numObjects++;
|
||
|
||
calcRV(&cfImages[item].current,item);
|
||
cfImages[item].current.x += 1;
|
||
cfImages[item].current.rot = 90;
|
||
}
|
||
|
||
cfImages[item].img = Tex;
|
||
cfImages[item].width = x;
|
||
cfImages[item].height = y;
|
||
cfImages[item].index = item;
|
||
strcpy(cfImages[item].name,name);
|
||
}
|
||
|
||
void YACReaderFlowGL::remove(int item)
|
||
{
|
||
//reposition current selection
|
||
if(item == currentSelected && currentSelected != 0){
|
||
currentSelected--;
|
||
}
|
||
|
||
int count = item;
|
||
while(count <= numObjects-2){
|
||
cfImages[count] = cfImages[count+1];
|
||
count++;
|
||
}
|
||
numObjects--;
|
||
cfImages = (CFImage*)realloc(cfImages,numObjects*sizeof(CFImage));
|
||
}
|
||
|
||
/*Info*/
|
||
CFImage YACReaderFlowGL::getCurrentSelected()
|
||
{
|
||
return cfImages[currentSelected];
|
||
}
|
||
|
||
void YACReaderFlowGL::replace(char *name, GLuint Tex, float x, float y,int item)
|
||
{
|
||
cfImages[item].img = Tex;
|
||
cfImages[item].width = x;
|
||
cfImages[item].height = y;
|
||
strcpy(cfImages[item].name,name);
|
||
loaded[item]=true;
|
||
}
|
||
|
||
void YACReaderFlowGL::populate(int n)
|
||
{
|
||
emit centerIndexChanged(0);
|
||
float x = 1;
|
||
float y = 1 * (700.f/480.0f);
|
||
int i;
|
||
|
||
for(i = 0;i<n;i++){
|
||
insert("cover", defaultTexture, x, y);
|
||
}
|
||
|
||
/*
|
||
for(int i = 0;i<n;i++){
|
||
QPixmap img = QPixmap(QString("./cover%1.jpg").arg(i+1));
|
||
GLuint cover = bindTexture(img, GL_TEXTURE_2D);
|
||
float y = 0.5 * (float(img.height())/img.width());
|
||
Insert("cover", cover, x, y);
|
||
}*/
|
||
|
||
loaded = QVector<bool>(n,false);
|
||
marks = QVector<bool>(n,false);
|
||
|
||
|
||
|
||
//worker->start();
|
||
}
|
||
|
||
void YACReaderFlowGL::reset()
|
||
{
|
||
currentSelected = 0;
|
||
loaded.clear();
|
||
for(int i = 0;i<numObjects;i++){
|
||
if(cfImages[i].img != defaultTexture)
|
||
deleteTexture(cfImages[i].img);
|
||
}
|
||
if(numObjects>0)
|
||
delete[] cfImages;
|
||
numObjects = 0;
|
||
|
||
}
|
||
|
||
void YACReaderFlowGL::reload()
|
||
{
|
||
int n = numObjects;
|
||
reset();
|
||
populate(n);
|
||
}
|
||
|
||
//slots
|
||
void YACReaderFlowGL::setCF_RX(int value)
|
||
{
|
||
config.cfRX = value;
|
||
}
|
||
void YACReaderFlowGL::setCF_RY(int value)
|
||
{
|
||
config.cfRY = value;
|
||
}
|
||
void YACReaderFlowGL::setCF_RZ(int value)
|
||
{
|
||
config.cfRZ = value;
|
||
}
|
||
|
||
void YACReaderFlowGL::setZoom(int zoom)
|
||
{
|
||
|
||
int width = this->width();
|
||
int height = this->height();
|
||
glViewport(0, 0, width, height);
|
||
|
||
glMatrixMode(GL_PROJECTION);
|
||
glLoadIdentity();
|
||
//float sideX = ((float(width)/height)/2)*1.5;
|
||
//float sideY = 0.5*1.5;
|
||
gluPerspective(zoom, (float)width / (float)height, 1.0, 200.0);
|
||
//glOrtho(-sideX, sideX, -sideY+0.2, +sideY+0.2, 4, 11.0);
|
||
|
||
glMatrixMode(GL_MODELVIEW);
|
||
|
||
}
|
||
|
||
void YACReaderFlowGL::setRotation(int angle)
|
||
{
|
||
config.rotation = -angle;
|
||
}
|
||
//sets the distance between the covers
|
||
void YACReaderFlowGL::setX_Distance(int distance)
|
||
{
|
||
config.xDistance = distance/100.0;
|
||
}
|
||
//sets the distance between the centered and the non centered covers
|
||
void YACReaderFlowGL::setCenter_Distance(int distance)
|
||
{
|
||
config.centerDistance = distance/100.0;
|
||
}
|
||
//sets the pushback amount
|
||
void YACReaderFlowGL::setZ_Distance(int distance)
|
||
{
|
||
config.zDistance = distance/100.0;
|
||
}
|
||
|
||
void YACReaderFlowGL::setCF_Y(int value)
|
||
{
|
||
config.cfY = value/100.0;
|
||
}
|
||
|
||
void YACReaderFlowGL::setCF_Z(int value)
|
||
{
|
||
config.cfZ = value;
|
||
}
|
||
|
||
void YACReaderFlowGL::setY_Distance(int value)
|
||
{
|
||
config.yDistance = value / 100.0;
|
||
}
|
||
|
||
void YACReaderFlowGL::setFadeOutDist(int value)
|
||
{
|
||
config.animationFadeOutDist = value;
|
||
}
|
||
|
||
void YACReaderFlowGL::setLightStrenght(int value)
|
||
{
|
||
config.viewRotateLightStrenght = value;
|
||
}
|
||
|
||
void YACReaderFlowGL::setMaxAngle(int value)
|
||
{
|
||
config.viewAngle = value;
|
||
}
|
||
|
||
void YACReaderFlowGL::setPreset(const Preset & p)
|
||
{
|
||
config = p;
|
||
}
|
||
|
||
void YACReaderFlowGL::setPerformance(Performance performance)
|
||
{
|
||
if(this->performance != performance)
|
||
{
|
||
this->performance = performance;
|
||
reload();
|
||
}
|
||
}
|
||
|
||
void YACReaderFlowGL::useVSync(bool b)
|
||
{
|
||
if(bUseVSync != b)
|
||
{
|
||
bUseVSync = b;
|
||
if(b)
|
||
{
|
||
QGLFormat f = format();
|
||
f.setSwapInterval(1);
|
||
setFormat(f);
|
||
}
|
||
else
|
||
{
|
||
QGLFormat f = format();
|
||
f.setSwapInterval(0);
|
||
setFormat(f);
|
||
}
|
||
reload();
|
||
}
|
||
}
|
||
void YACReaderFlowGL::setShowMarks(bool value)
|
||
{
|
||
showMarks = value;
|
||
}
|
||
void YACReaderFlowGL::setMarks(QVector<bool> marks)
|
||
{
|
||
this->marks = marks;
|
||
}
|
||
void YACReaderFlowGL::setMarkImage(QImage & image)
|
||
{
|
||
//qu<71> pasa la primera vez??
|
||
//deleteTexture(markTexture);
|
||
//markTexture = bindTexture(image,GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption);
|
||
}
|
||
void YACReaderFlowGL::markSlide(int index)
|
||
{
|
||
marks[index] = true;
|
||
}
|
||
void YACReaderFlowGL::unmarkSlide(int index)
|
||
{
|
||
marks[index] = false;
|
||
}
|
||
void YACReaderFlowGL::setSlideSize(QSize size)
|
||
{
|
||
//TODO calcular el tama<6D>o del widget
|
||
}
|
||
void YACReaderFlowGL::clear()
|
||
{
|
||
reset();
|
||
}
|
||
|
||
void YACReaderFlowGL::setCenterIndex(int index)
|
||
{
|
||
setCurrentIndex(index);
|
||
}
|
||
void YACReaderFlowGL::showSlide(int index)
|
||
{
|
||
setCurrentIndex(index);
|
||
}
|
||
int YACReaderFlowGL::centerIndex()
|
||
{
|
||
return currentSelected;
|
||
}
|
||
void YACReaderFlowGL::updateMarks()
|
||
{
|
||
//do nothing
|
||
}
|
||
/*void YACReaderFlowGL::setFlowType(FlowType flowType)
|
||
{
|
||
//TODO esperar a que se reimplemente flowtype
|
||
}*/
|
||
void YACReaderFlowGL::render()
|
||
{
|
||
//do nothing
|
||
}
|
||
|
||
//EVENTOS
|
||
void YACReaderFlowGL::wheelEvent(QWheelEvent * event)
|
||
{
|
||
if(event->delta()<0)
|
||
showNext();
|
||
else
|
||
showPrevious();
|
||
event->accept();
|
||
}
|
||
|
||
void YACReaderFlowGL::keyPressEvent(QKeyEvent *event)
|
||
{
|
||
if(event->key() == Qt::Key_Left)
|
||
{
|
||
if(event->modifiers() == Qt::ControlModifier)
|
||
setCurrentIndex((currentSelected-10<0)?0:currentSelected-10);
|
||
else
|
||
showPrevious();
|
||
event->accept();
|
||
return;
|
||
}
|
||
|
||
if(event->key() == Qt::Key_Right)
|
||
{
|
||
if(event->modifiers() == Qt::ControlModifier)
|
||
setCurrentIndex((currentSelected+10>=numObjects)?numObjects-1:currentSelected+10);
|
||
else
|
||
showNext();
|
||
event->accept();
|
||
return;
|
||
}
|
||
|
||
event->ignore();
|
||
}
|
||
|
||
void YACReaderFlowGL::mousePressEvent(QMouseEvent *event)
|
||
{
|
||
if(event->button() == Qt::LeftButton)
|
||
{
|
||
float x,y;
|
||
x = event->x();
|
||
y = event->y();
|
||
GLint viewport[4];
|
||
GLdouble modelview[16];
|
||
GLdouble projection[16];
|
||
GLfloat winX, winY, winZ;
|
||
GLdouble posX, posY, posZ;
|
||
|
||
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
|
||
glGetDoublev( GL_PROJECTION_MATRIX, projection );
|
||
glGetIntegerv( GL_VIEWPORT, viewport );
|
||
|
||
winX = (float)x;
|
||
winY = (float)viewport[3] - (float)y;
|
||
glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
|
||
|
||
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
|
||
|
||
if(posX >= 0.5)
|
||
{
|
||
//int index = currentSelected+1;
|
||
//while((cfImages[index].current.x-cfImages[index].width/(2.0*config.rotation)) < posX)
|
||
// index++;
|
||
//setCurrentIndex(index-1);
|
||
showNext();
|
||
}
|
||
else if(posX <=-0.5)
|
||
showPrevious();
|
||
} else
|
||
QGLWidget::mousePressEvent(event);
|
||
}
|
||
|
||
void YACReaderFlowGL::mouseDoubleClickEvent(QMouseEvent* event)
|
||
{
|
||
emit selected(centerIndex());
|
||
event->accept();
|
||
}
|
||
|
||
YACReaderComicFlowGL::YACReaderComicFlowGL(QWidget *parent,struct Preset p )
|
||
:YACReaderFlowGL(parent,p)
|
||
{
|
||
worker = new ImageLoaderGL(this);
|
||
worker->flow = this;
|
||
}
|
||
|
||
void YACReaderComicFlowGL::setImagePaths(QStringList paths)
|
||
{
|
||
worker->reset();
|
||
reset();
|
||
numObjects = 0;
|
||
if(lazyPopulateObjects!=-1)
|
||
YACReaderFlowGL::populate(paths.size());
|
||
lazyPopulateObjects = paths.size();
|
||
this->paths = paths;
|
||
//numObjects = paths.size();
|
||
}
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
void YACReaderComicFlowGL::updateImageData()
|
||
{
|
||
// can't do anything, wait for the next possibility
|
||
if(worker->busy())
|
||
return;
|
||
|
||
// set image of last one
|
||
int idx = worker->index();
|
||
if( idx >= 0 && !worker->result().isNull())
|
||
{
|
||
if(!loaded[idx])
|
||
{
|
||
float x = 1;
|
||
QImage img = worker->result();
|
||
GLuint cover;
|
||
if(performance == high || performance == ultraHigh)
|
||
cover = bindTexture(img, GL_TEXTURE_2D,GL_RGB,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption);
|
||
else
|
||
cover = bindTexture(img, GL_TEXTURE_2D,GL_RGB,QGLContext::LinearFilteringBindOption);
|
||
float y = 1 * (float(img.height())/img.width());
|
||
replace("cover", cover, x, y,idx);
|
||
/*CFImages[idx].width = x;
|
||
CFImages[idx].height = y;
|
||
CFImages[idx].img = worker->resultTexture;
|
||
strcpy(CFImages[idx].name,"cover");*/
|
||
loaded[idx] = true;
|
||
//numImagesLoaded++;
|
||
}
|
||
}
|
||
|
||
// try to load only few images on the left and right side
|
||
// i.e. all visible ones plus some extra
|
||
int count=8;
|
||
switch(performance)
|
||
{
|
||
case low:
|
||
count = 8;
|
||
break;
|
||
case medium:
|
||
count = 10;
|
||
break;
|
||
case high:
|
||
count = 12;
|
||
break;
|
||
case ultraHigh:
|
||
count = 14;
|
||
break;
|
||
}
|
||
int * indexes = new int[2*count+1];
|
||
int center = currentSelected;
|
||
indexes[0] = center;
|
||
for(int j = 0; j < count; j++)
|
||
{
|
||
indexes[j*2+1] = center+j+1;
|
||
indexes[j*2+2] = center-j-1;
|
||
}
|
||
for(int c = 0; c < 2*count+1; c++)
|
||
{
|
||
int i = indexes[c];
|
||
if((i >= 0) && (i < numObjects))
|
||
if(!loaded[i])//slide(i).isNull())
|
||
{
|
||
//loader->loadTexture(i);
|
||
//loaded[i]=true;
|
||
// schedule thumbnail generation
|
||
if(paths.size()>0)
|
||
{
|
||
QString fname = paths.at(i);
|
||
//loaded[i]=true;
|
||
|
||
worker->generate(i, fname);
|
||
}
|
||
delete[] indexes;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
YACReaderPageFlowGL::YACReaderPageFlowGL(QWidget *parent,struct Preset p )
|
||
:YACReaderFlowGL(parent,p)
|
||
{
|
||
worker = new ImageLoaderByteArrayGL(this);
|
||
worker->flow = this;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
void YACReaderPageFlowGL::updateImageData()
|
||
{
|
||
// can't do anything, wait for the next possibility
|
||
if(worker->busy())
|
||
return;
|
||
|
||
// set image of last one
|
||
int idx = worker->index();
|
||
if( idx >= 0 && !worker->result().isNull())
|
||
{
|
||
if(!loaded[idx])
|
||
{
|
||
float x = 1;
|
||
QImage img = worker->result();
|
||
GLuint cover;
|
||
if(performance == high || performance == ultraHigh)
|
||
cover = bindTexture(img, GL_TEXTURE_2D,GL_RGB,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption);
|
||
else
|
||
cover = bindTexture(img, GL_TEXTURE_2D,GL_RGB,QGLContext::LinearFilteringBindOption);
|
||
float y = 1 * (float(img.height())/img.width());
|
||
replace("cover", cover, x, y,idx);
|
||
/*CFImages[idx].width = x;
|
||
CFImages[idx].height = y;
|
||
CFImages[idx].img = worker->resultTexture;
|
||
strcpy(CFImages[idx].name,"cover");*/
|
||
loaded[idx] = true;
|
||
//numImagesLoaded++;
|
||
}
|
||
}
|
||
|
||
// try to load only few images on the left and right side
|
||
// i.e. all visible ones plus some extra
|
||
int count=8;
|
||
switch(performance)
|
||
{
|
||
case low:
|
||
count = 8;
|
||
break;
|
||
case medium:
|
||
count = 10;
|
||
break;
|
||
case high:
|
||
count = 12;
|
||
break;
|
||
case ultraHigh:
|
||
count = 14;
|
||
break;
|
||
}
|
||
int * indexes = new int[2*count+1];
|
||
int center = currentSelected;
|
||
indexes[0] = center;
|
||
for(int j = 0; j < count; j++)
|
||
{
|
||
indexes[j*2+1] = center+j+1;
|
||
indexes[j*2+2] = center-j-1;
|
||
}
|
||
for(int c = 0; c < 2*count+1; c++)
|
||
{
|
||
int i = indexes[c];
|
||
if((i >= 0) && (i < numObjects))
|
||
if(rawImages.size()>0)
|
||
|
||
if(!loaded[i]&&imagesReady[i])//slide(i).isNull())
|
||
{
|
||
//loader->loadTexture(i);
|
||
//loaded[i]=true;
|
||
// schedule thumbnail generation
|
||
|
||
//loaded[i]=true;
|
||
|
||
worker->generate(i, rawImages.at(i));
|
||
|
||
delete[] indexes;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
void YACReaderPageFlowGL::populate(int n)
|
||
{
|
||
worker->reset();
|
||
if(lazyPopulateObjects!=-1)
|
||
YACReaderFlowGL::populate(n);
|
||
lazyPopulateObjects = n;
|
||
imagesReady = QVector<bool> (n,false);
|
||
rawImages = QVector<QByteArray> (n);
|
||
imagesSetted = QVector<bool> (n,false); //puede sobrar
|
||
}
|
||
|
||
|
||
//-----------------------------------------------------------------------------
|
||
//ImageLoader
|
||
//-----------------------------------------------------------------------------
|
||
QImage ImageLoaderGL::loadImage(const QString& fileName)
|
||
{
|
||
QImage image;
|
||
bool result = image.load(fileName);
|
||
|
||
switch(flow->performance)
|
||
{
|
||
case low:
|
||
image = image.scaledToWidth(200,Qt::SmoothTransformation);
|
||
break;
|
||
case medium:
|
||
image = image.scaledToWidth(256,Qt::SmoothTransformation);
|
||
break;
|
||
case high:
|
||
image = image.scaledToWidth(320,Qt::SmoothTransformation);
|
||
break;
|
||
|
||
}
|
||
|
||
if(!result)
|
||
return QImage();
|
||
|
||
return image;
|
||
}
|
||
|
||
ImageLoaderGL::ImageLoaderGL(YACReaderFlowGL * flow):
|
||
QThread(),flow(flow),restart(false), working(false), idx(-1)
|
||
{
|
||
|
||
}
|
||
|
||
ImageLoaderGL::~ImageLoaderGL()
|
||
{
|
||
mutex.lock();
|
||
condition.wakeOne();
|
||
mutex.unlock();
|
||
wait();
|
||
}
|
||
|
||
bool ImageLoaderGL::busy() const
|
||
{
|
||
return isRunning() ? working : false;
|
||
}
|
||
|
||
void ImageLoaderGL::generate(int index, const QString& fileName)
|
||
{
|
||
mutex.lock();
|
||
this->idx = index;
|
||
this->fileName = fileName;
|
||
this->size = size;
|
||
this->img = QImage();
|
||
mutex.unlock();
|
||
|
||
if (!isRunning())
|
||
start();
|
||
else
|
||
{
|
||
// already running, wake up whenever ready
|
||
restart = true;
|
||
condition.wakeOne();
|
||
}
|
||
}
|
||
|
||
void ImageLoaderGL::run()
|
||
{
|
||
for(;;)
|
||
{
|
||
// copy necessary data
|
||
mutex.lock();
|
||
this->working = true;
|
||
QString fileName = this->fileName;
|
||
mutex.unlock();
|
||
|
||
QImage image = loadImage(fileName);
|
||
|
||
// let everyone knows it is ready
|
||
mutex.lock();
|
||
this->working = false;
|
||
this->img = image;
|
||
mutex.unlock();
|
||
|
||
// put to sleep
|
||
mutex.lock();
|
||
if (!this->restart)
|
||
condition.wait(&mutex);
|
||
restart = false;
|
||
mutex.unlock();
|
||
}
|
||
}
|
||
|
||
QImage ImageLoaderGL::result()
|
||
{
|
||
return img;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
//ImageLoader
|
||
//-----------------------------------------------------------------------------
|
||
QImage ImageLoaderByteArrayGL::loadImage(const QByteArray& raw)
|
||
{
|
||
QImage image;
|
||
bool result = image.loadFromData(raw);
|
||
|
||
switch(flow->performance)
|
||
{
|
||
case low:
|
||
image = image.scaledToWidth(128,Qt::SmoothTransformation);
|
||
break;
|
||
case medium:
|
||
image = image.scaledToWidth(196,Qt::SmoothTransformation);
|
||
break;
|
||
case high:
|
||
image = image.scaledToWidth(256,Qt::SmoothTransformation);
|
||
break;
|
||
case ultraHigh:
|
||
image = image.scaledToWidth(320,Qt::SmoothTransformation);
|
||
break;
|
||
}
|
||
|
||
if(!result)
|
||
return QImage();
|
||
|
||
return image;
|
||
}
|
||
|
||
ImageLoaderByteArrayGL::ImageLoaderByteArrayGL(YACReaderFlowGL * flow):
|
||
QThread(),flow(flow),restart(false), working(false), idx(-1)
|
||
{
|
||
|
||
}
|
||
|
||
ImageLoaderByteArrayGL::~ImageLoaderByteArrayGL()
|
||
{
|
||
mutex.lock();
|
||
condition.wakeOne();
|
||
mutex.unlock();
|
||
wait();
|
||
}
|
||
|
||
bool ImageLoaderByteArrayGL::busy() const
|
||
{
|
||
return isRunning() ? working : false;
|
||
}
|
||
|
||
void ImageLoaderByteArrayGL::generate(int index, const QByteArray& raw)
|
||
{
|
||
mutex.lock();
|
||
this->idx = index;
|
||
this->rawData = raw;
|
||
this->size = size;
|
||
this->img = QImage();
|
||
mutex.unlock();
|
||
|
||
if (!isRunning())
|
||
start();
|
||
else
|
||
{
|
||
// already running, wake up whenever ready
|
||
restart = true;
|
||
condition.wakeOne();
|
||
}
|
||
}
|
||
|
||
void ImageLoaderByteArrayGL::run()
|
||
{
|
||
for(;;)
|
||
{
|
||
// copy necessary data
|
||
mutex.lock();
|
||
this->working = true;
|
||
QByteArray raw = this->rawData;
|
||
mutex.unlock();
|
||
|
||
QImage image = loadImage(raw);
|
||
|
||
// let everyone knows it is ready
|
||
mutex.lock();
|
||
this->working = false;
|
||
this->img = image;
|
||
mutex.unlock();
|
||
|
||
// put to sleep
|
||
mutex.lock();
|
||
if (!this->restart)
|
||
condition.wait(&mutex);
|
||
restart = false;
|
||
mutex.unlock();
|
||
}
|
||
}
|
||
|
||
QImage ImageLoaderByteArrayGL::result()
|
||
{
|
||
return img;
|
||
}
|
||
|
||
//WidgetLoader::WidgetLoader(QWidget *parent, QGLWidget * shared)
|
||
// :QGLWidget(parent,shared)
|
||
//{
|
||
//}
|
||
//
|
||
//void WidgetLoader::loadTexture(int index)
|
||
//{
|
||
// QImage image;
|
||
// bool result = image.load(QString("./cover%1.jpg").arg(index+1));
|
||
// //image = image.scaledToWidth(128,Qt::SmoothTransformation); //TODO parametrizar
|
||
// flow->cfImages[index].width = 0.5;
|
||
// flow->cfImages[index].height = 0.5 * (float(image.height())/image.width());
|
||
// flow->cfImages[index].img = bindTexture(image, GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption);
|
||
//}
|