一个Qt OpenGl编写的图片晃动效果
时间:2010-12-20 来源:landuochong
头文件 andy.h
#ifndef ANDY_H
#define ANDY_H
#include <qgl.h>
#include <QMouseEvent>
#include <QtGui>
#include <QtCore>
#include <QtOpenGL>
class AndyWidget : public QGLWidget
{
Q_OBJECT
public:
AndyWidget( QWidget* parent = 0, const char* name = 0);
~AndyWidget();
protected:
void newPaint();
void initializeGL(); //initiate opengl window content
void paintGL();
void resizeGL( int width, int height ); //deal with the matter when the size of the window is changed
void loadGLTextures(); //load the textures
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
protected:
int num;
// float speed,distant;
float k;
// int status;
GLfloat zoom,xoom,yoom;
GLuint texture[10]; //store the texture
float oldx,oldy; //store the station of where mouse be preessed
float releasex,releasey; //store the station of where the mouse be released
private:
QPoint lastPos,pressPos;
};
#endif//ANDY_H
源文件 andy.cpp
#include <qimage.h>
#include <QMouseEvent>
#include "andy.h"
#include<math.h>
#include<iostream.h>
/*************************************************/
AndyWidget::AndyWidget( QWidget* parent, const char* name)
: QGLWidget( parent, name )
{
num=1;
oldx=oldy=releasex=releasey=0;
zoom = -5.0;
xoom = 0.0;
yoom = 0.0;
setGeometry( 0, 0, 800, 480 );
setCaption( "sway special efficacy" );
}
/************************************************/
AndyWidget::~AndyWidget()
{
}
/******************************************************/
void AndyWidget::mousePressEvent(QMouseEvent *event)
{
oldx=float(event->x()); //record the oldx value
oldy=float(event->y()); //record the oldy value
cout<<"oldx="<<oldx<<endl;
cout<<"oldy="<<oldy<<endl;
lastPos = event->pos();
}
/*********************************************************/
void AndyWidget::mouseMoveEvent(QMouseEvent *event)
{
float dx = float(event->x() - lastPos.x());
float dy = float(event->y() - lastPos.y());
yoom -= (dy/100);
xoom += (dx/100);
lastPos = event->pos();
updateGL();
}
/************************************************/
void AndyWidget::mouseReleaseEvent(QMouseEvent *event)
{
int choice,i;
releasex=float(event->x()); //record the current x value of where the mouse is released
releasey=float(event->y()); //record the current y value of where the mouse is released
cout<<"releasex="<<releasex<<endl;
cout<<"releasey="<<releasey<<endl;
if(((releasey-oldy)!=0)&&((releasex-oldx)!=0))
{
k=(releasey-oldy)/(releasex-oldx); //compute the k
cout<<"the tan k="<<k<<endl;
}
if(((releasey-oldy)==0)&&((releasex-oldx)==0)) //don't move****0
{
num+=1;
if(num>8)
num=1;
choice=0;
cout<<"choice0="<<choice<<endl;
}
if(((releasey-oldy)==0)&&((releasex-oldx)<0)) //west direction****1
{
num=1;
choice=1;
cout<<"choice1="<<choice<<endl;
}
if(((releasey-oldy)==0)&&((releasex-oldx)>0)) //east direction****2
{ num=2;
choice=2;
cout<<"choice2="<<choice<<endl;
}
if(((releasey-oldy)>0)&&((releasex-oldx)==0)) //south direction****3
{
num=3;
choice=3;
cout<<"choice3="<<choice<<endl;
}
if(((releasey-oldy)<0)&&((releasex-oldx)==0)) //north direction****4
{
num=4;
choice=4;
cout<<"choice4="<<choice<<endl;
}
if(((releasey-oldy)>0)&&((releasex-oldx)>0)) //southeast direction****5
{
num=5;
choice=5;
cout<<"choice5="<<choice<<endl;
}
if(((releasey-oldy)>0)&&((releasex-oldx)<0)) //southwest direction****6
{
num=6;
choice=6;
cout<<"choice6="<<choice<<endl;
}
if(((releasey-oldy)<0)&&((releasex-oldx)<0)) //northwest direction****7
{
num=7;
updateGL();
choice=7;
cout<<"choice7="<<choice<<endl;
}
if(((releasey-oldy)<0)&&((releasex-oldx)>0)) //northeast direction****8
{
num=8;
updateGL();
choice=8;
cout<<"choice8="<<choice<<endl;
}
//the fellowing sentence to deal with the matter
switch(choice)
{
case 0:
updateGL();
xoom=yoom=0.0;
updateGL();
for(i=0;i<2;i++)
{
xoom+=0.01;
yoom-=0.01;
updateGL();
}
xoom=yoom=0.0;
updateGL();
for(i=0;i<2;i++)
{
xoom-=0.01;
yoom-=0.01;
updateGL();
}
xoom=yoom=0.0;
updateGL();
for(i=0;i<2;i++)
{
xoom-=0.01;
yoom+=0.01;
updateGL();
}
xoom=yoom=0.0;
updateGL();
for(i=0;i<2;i++)
{
xoom+=0.01;
yoom+=0.01;
updateGL();
}
xoom=yoom=0.0;
updateGL();
break;
case 1:
updateGL();
{ yoom=0.0;
xoom=0.5;
updateGL();
while(xoom>-0.4)
{xoom-=0.1;updateGL();}
while(xoom<0.2)
{xoom+=0.03;updateGL();}
while(xoom>-0.1)
{xoom-=0.02;updateGL();}
xoom=0.0;updateGL();
}
break;
case 2:
updateGL();
{
yoom=0.0;
xoom=-0.5;
updateGL();
while(xoom<0.4)
{xoom+=0.1;updateGL();}
while(xoom>-0.3)
{xoom-=0.03;updateGL();}
while(xoom<0.1)
{xoom+=0.02;updateGL();}
xoom=0.0;updateGL();
}
break;
case 3:
xoom=0.0;
yoom=0.5;
updateGL();
while(yoom>-0.4)
{yoom-=0.1;updateGL();}
while(yoom<0.3)
{yoom+=0.03;updateGL();}
while(yoom>-0.1)
{yoom-=0.02;updateGL();}
yoom=0.0;updateGL();
break;
case 4:
xoom=0.0;
yoom=-0.5;
updateGL();
while(yoom<0.4)
{yoom+=0.1;updateGL();}
while(yoom>-0.3)
{yoom-=0.03;updateGL();}
while(yoom<0.1)
{yoom+=0.02;updateGL();}
yoom=0.0;updateGL();
break;
case 5:
{
k=fabs(k);
if(k>2.5) //resume as the same choice 3
{
xoom=0.0;
yoom=0.5;
updateGL();
while(yoom>-0.4)
{yoom-=0.1;updateGL();}
while(yoom<0.3)
{yoom+=0.03;updateGL();}
while(yoom>-0.1)
{yoom-=0.02;updateGL();}
yoom=0.0;updateGL();
}
else
{ xoom=-0.4;yoom=-k*xoom;updateGL();
while(xoom<0.3)
{ xoom+=0.1;yoom-=k*0.1;updateGL();}
while(xoom>-0.2)
{xoom-=0.03;yoom+=k*0.03;updateGL();}
while(xoom<0.1)
{ xoom+=0.02;yoom-=k*0.02;updateGL();}
xoom=yoom=0.0;updateGL();
}
}
break;
case 6:
{
k=fabs(k);
if(k>2.5) //resume as the same choice 3
{
xoom=0.0;
yoom=0.5;
updateGL();
while(yoom>-0.4)
{yoom-=0.1;updateGL();}
while(yoom<0.3)
{yoom+=0.03;updateGL();}
while(yoom>-0.1)
{yoom-=0.02;updateGL();}
yoom=0.0;updateGL();
}
// k=0.5;
else
{
xoom=0.4;yoom=k*xoom;updateGL();
while(xoom>-0.3)
{ xoom-=0.1;yoom-=k*0.1;updateGL();}
while(xoom<0.2)
{xoom+=0.03;yoom+=k*0.03;updateGL();}
while(xoom>-0.1)
{ xoom-=0.02;yoom-=k*0.02;updateGL();}
xoom=yoom=0.0;updateGL();
}
}
break;
case 7:
{
k=fabs(k);
if(k>2.5) //resume as the same the choice 4
{ xoom=0.0;
yoom=-0.5;
updateGL();
while(yoom<0.4)
{yoom+=0.1;updateGL();}
while(yoom>-0.3)
{yoom-=0.03;updateGL();}
while(yoom<0.1)
{yoom+=0.02;updateGL();}
yoom=0.0;updateGL();
}
else
{
xoom=0.4;yoom=-k*xoom;updateGL();
while(xoom>-0.3)
{ xoom-=0.1;yoom+=k*0.1;updateGL();}
while(xoom<0.2)
{xoom+=0.03;yoom-=k*0.03;updateGL();}
while(xoom>-0.1)
{ xoom-=0.02;yoom+=k*0.02;updateGL();}
xoom=yoom=0.0;updateGL();
}
}
break;
case 8:
{
k=fabs(k);
if(k>2.5) //resume as the same the choice 4
{ xoom=0.0;
yoom=-0.4;
updateGL();
while(yoom<0.3)
{yoom+=0.1;updateGL();}
while(yoom>-0.2)
{yoom-=0.03;updateGL();}
while(yoom<0.1)
{yoom+=0.02;updateGL();}
yoom=0.0;updateGL();
}
else
{
xoom=-0.4;yoom=k*xoom;updateGL();
while(xoom<0.3)
{ xoom+=0.1;yoom+=k*0.1;updateGL();}
while(xoom>-0.2)
{xoom-=0.03;yoom-=k*0.03;updateGL();}
while(xoom<0.1)
{ xoom+=0.02;yoom+=k*0.02;updateGL();}
xoom=yoom=0.0;updateGL();
}
}
break;
default:
break;
}
}
/****************************************************/
void AndyWidget::newPaint()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
glTranslatef( xoom, yoom, zoom );
glBindTexture( GL_TEXTURE_2D, texture[num] );
glBegin( GL_QUADS ); //paint the quads
glTexCoord2f( 0.0, 1.0 );glVertex3f( -1.0, 1.0, 0.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 0.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, -1.0, 0.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, 0.0 );
glEnd();
glLoadIdentity();
glTranslatef(-3.0,0.0,-4.9);
glBindTexture( GL_TEXTURE_2D, texture[0] );
glBegin( GL_QUADS );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.5, -1.0, 1.0 ); //1
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.5, 1.0, 1.0 );
glEnd();
glBindTexture( GL_TEXTURE_2D, texture[4] );
glBegin( GL_QUADS );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.5, -1.0, -1.0 ); //3
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.5, 1.0, -1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.2, 1.0, -1.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.2, -1.0, -1.0 );
glEnd();
glBindTexture( GL_TEXTURE_2D, texture[3] );
glBegin( GL_QUADS );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.5, 1.0, -1.0 ); //5
glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.5, 1.0, 1.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 1.0, 1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, -1.0 );
glEnd();
glBindTexture( GL_TEXTURE_2D, texture[2] );
glBegin( GL_QUADS );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.5, -1.0, -1.0 ); //6
glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, -1.0, -1.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.5, -1.0, 1.0 );
glEnd();
glBindTexture( GL_TEXTURE_2D, texture[num] );
glBegin( GL_QUADS );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.2, -1.0, -1.0 ); //4
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.2, 1.0, -1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 );
glEnd();
glBindTexture( GL_TEXTURE_2D, texture[0] );
glBegin( GL_QUADS );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.5, -1.0, -1.0 ); //2
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.5, -1.0, 1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.5, 1.0, 1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.5, 1.0, -1.0 );
glEnd();
}
/***************paintGL()***********************/
void AndyWidget::paintGL()
{
newPaint();
}
/***************initialzeGL()**********************/
void AndyWidget::initializeGL()
{
loadGLTextures();
glEnable( GL_TEXTURE_2D );
glShadeModel( GL_SMOOTH );
glClearColor( 0.5, 0.4, 0.3, 0.5 );
glClearDepth( 1.0 ); //set the depth buffer
glEnable( GL_DEPTH_TEST ); //start the depth test
glDepthFunc( GL_LEQUAL ); //depth test type
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
}
/*************************************************/
void AndyWidget::resizeGL( int width, int height )
{
if ( height == 0 )
{
height = 1;
}
glViewport( 0, 0, (GLint)width, (GLint)height ); //reset the viewport
glMatrixMode( GL_PROJECTION ); //choose the matrimode
glLoadIdentity();
gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 ); //set the matrimode
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
/****************************************************/
void AndyWidget::loadGLTextures()
{ int j;
QImage tex[9], buf[9];
if ( !buf[0].load( "./data/p.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
}
if ( !buf[1].load( "./data/1.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
}
if ( !buf[2].load( "./data/2.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
}
if ( !buf[3].load( "./data/3.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
}
if ( !buf[4].load( "./data/4.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
}
if ( !buf[5].load( "./data/5.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
}
if ( !buf[6].load( "./data/6.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
}
if ( !buf[7].load( "./data/7.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
}
if ( !buf[8].load( "./data/8.bmp" ) )
{
qWarning( "Could not read image file, using single-color instead." );
;
}
//****************
for(j=0;j<9;j++)
{
tex[j] = QGLWidget::convertToGLFormat( buf[j] );
}
glGenTextures( 9, &texture[0] );
for(j=0;j<9;j++)
{
glBindTexture( GL_TEXTURE_2D, texture[j] );
glTexImage2D( GL_TEXTURE_2D, 0, 3, tex[j].width(), tex[j].height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, tex[j].bits() );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
}
main.cpp
测试用的
#include <qapplication.h>
#include <qmessagebox.h>
#include "Andy.h"
int main( int argc, char **argv )
{
bool fs = false;
QApplication a(argc,argv);
AndyWidget w( 0, 0);
a.setMainWidget( &w );
w.show();
return a.exec();
}
note: Linux环境下gcc统计器,QT4+QTOPENGL+openGL工具
qt3到qt4的转换 命令行输入
#qt3to4 *.pro
在工程文件中加入:
QT += Opengl
QT +=qt3support opengl
添加QT4的环境变量
# vim /root/.bashrc
在文件的末尾添加
export PATH=(QT4的安装路径):$PATH
保存后退出后,重起终端就OK了
http://blog.csdn.net/yang_rong_yong/archive/2008/08/20/2799482.aspx