QT+OPenGL绘图例子

环境:Qt4.7.3 + VS2008

效果图:

 QT+OPenGL绘图例子_第1张图片

//***************  glutttt.h

#ifndef GLUTTTT_H

#define GLUTTTT_H

 

#include

#include

#include

#include

 

#pragma comment(lib, "glaux.lib")

 

class glutttt : public QGLWidget

{

       Q_OBJECT

 

public:

       glutttt(QWidget *parent = 0);

       ~glutttt();

       void loadGLTextures();//载入纹理

       void buildLists();//创建列表

       void drawList();//画列表

       void drawFlag();//画旗子

       void drawSphere();//画球体

       int drawGLobject();

 

       void initializeGL();//初始化QpenGL窗口部件

       void paintGL();//绘制QPenGL窗口,有更新发生,函数就会被调用

       void resizeGL(int w, int h);//处理窗口大小变化,w和h是新状态下的宽和高,完成后自动刷新屏幕

       //void keyPressEvent(QKeyEvent *e);//鼠标按下事件处理函数

       void timerEvent(QTimerEvent *);//实现窗口部件的定时操作

       void mousePressEvent(QMouseEvent *e);//鼠标单击事件

       void mouseMoveEvent(QMouseEvent *e);//鼠标移动事件

       void mouseReleaseEvent(QMouseEvent *e);//鼠标释放事件

       void wheelEvent(QWheelEvent *e);//鼠标滚轮事件

 

       bool fullScreen;

       GLfloat xrot,yrot,zrot;

       GLfloat zoom;

       GLfloat hold;//存放用来对旗光滑的浮点数

       GLuint texture[4];//四个纹理

       GLuint box,top,tri;//存放显示列表的指针

       GLuint xLoop,yLoop;//表示两个立方体位置的变量

 

       GLfloat sphere_x,sphere_y;

 

       bool light;

       bool blend;

 

       float points[45][45][3];//存放网格各顶点独立地(x,y,z)坐标

       int wiggle_count;//指定波浪的速度

 

       GLuint fogFilter;//选择雾的类型

       GLuint filter;//储存纹理变量

       QPoint lastPos;

       GLUquadric *qobj;//二次方程对象

 

       int part1;//圆盘的起始角度

       int part2;//圆盘的结束角度

       int p1;//增量

       int p2;//增量

       GLuint obj;//要画的对象

 

       bool sp;//空格键是否按下

};

 

#endif // glutttt_H

 

//************** glutttt.cpp

#include "glutttt.h"

#include

#include

#include

 

static GLfloat boxcol[5][3] = {

 

       {1.0,0.0,0.0},

       {1.0,0.5,0.0},

       {1.0,1.0,0.0},

       {0.0,1.0,0.0},

       {0.0,1.0,1.0}

};

static GLfloat topcol[5][3] = {

 

       {0.5,0.0,0.0},

       {0.5,0.25,0.0},

       {0.5,0.5,0.0},

       {0.5,0.0,0.0},

       {0.0,0.5,0.5}

};//两个颜色数组

 

//设置光源

GLfloat lightAmbient[4] = {0.5,0.5,0.5,1.0};

GLfloat lightDiffuse[4] = {1.0,1.0,1.0,1.0};

GLfloat lightPosition[4] = {0.0,0.0,2.0,1.0};

 

//雾的设定

GLuint fogMode[3] = {GL_EXP,GL_EXP2,GL_LINEAR};//三种雾的效果,依次递进

GLfloat fogColor[4] = {0.5,0.5,1.0,0.3};

 

glutttt::glutttt(QWidget *parent)

: QGLWidget(parent)

{

       xrot = yrot = zrot = 0;

       zoom = -10.0;

       hold = 0.0;

       box = top = tri = 0;

       xLoop = yLoop = 0;

       fogFilter = 3;

       wiggle_count = 0;

       filter = 0;

       light = false;

       blend = false;

       fullScreen = false;

 

       sphere_x = 2.0;

       sphere_y = 0;

 

       obj =0;

 

       p1 = 0;

       p2 = 1;

       part1 = 0;

       part2 = 0;

 

       setGeometry(50,50,800,600);

       if (fullScreen)

       {

              showFullScreen();

       }

       startTimer(5);

}

void glutttt::initializeGL()

{

       loadGLTextures();//先载入纹理

       buildLists();//建立列表

       glEnable(GL_TEXTURE_2D);//启用纹理

       glShadeModel(GL_SMOOTH);//阴影平滑

       glClearColor(0.0,0.0,0.0,0.5);//设置清除屏幕时所使用的颜色

       glClearDepth(1.0);//设置深度缓存

       glEnable(GL_DEPTH_TEST);//启用深度测试

       glDepthFunc(GL_LEQUAL);//所做深度测试的类型

       glEnable(GL_COLOR_MATERIAL);//可以用颜色来帖纹理

       glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);//投影修正

 

       glPolygonMode(GL_BACK,GL_FILL);//背景

       glPolygonMode(GL_FRONT,GL_FILL);//前景

 

       //灯

       glLightfv(GL_LIGHT1,GL_AMBIENT,lightAmbient);

       glLightfv(GL_LIGHT1,GL_DIFFUSE,lightDiffuse);

       glLightfv(GL_LIGHT1,GL_POSITION,lightPosition);

       glEnable(GL_LIGHT1);

 

       //雾

       glFogi(GL_FOG_MODE,fogMode[fogFilter]);

       glFogfv(GL_FOG_COLOR,fogColor);

       glFogf(GL_FOG_DENSITY,0.1);//雾的浓度

       glHint(GL_FOG_HINT,GL_DONT_CARE);//确定雾的渲染方式,不关心建议值,GL_NICEST极棒的,每一像素渲染,GL_FASTEST对每一顶点渲染,速度快

       glFogf(GL_FOG_START,1.0);//雾离屏幕的距离

       glFogf(GL_FOG_END,5.0);

       //glEnable(GL_FOG);

 

       //融合

       glColor4f(1.0,1.0,1.0,0.5);

       glBlendFunc(GL_SRC_ALPHA,GL_ONE);

 

       //初始化网格的点,整数循环可以消除浮点数运算取整造成的脉冲锯齿出现

       for (int x=0;x<45;x++)

       {

              for (int y=0;y<45;y++)

              {

                     points[x][y][0] = float((x/5.0)-5.0);//使波浪居中【-4.5~4.5】

                     points[x][y][1] = float((y/5.0)-5.0);

                     points[x][y][2] = float(sin((((x/5.0)*40.0)/360.0)*3.141592654*2.0));

              }

       }

}

 

void glutttt::buildLists()

{

       box = glGenLists(3);//建立两个显示列表,box指向第一个列表

       glNewList(box,GL_COMPILE);//把列表存储到box所指空间,第二个参数预先在内存中构造这个列表,COMPILE相当于编程,调用的是已经变异好的盒子

       glBegin(GL_QUADS);

       //第一个

       glNormal3f(0.0,-1.0,0.0);

       glTexCoord2f(1.0,1.0);glVertex3f(-1.0,-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);

       glTexCoord2f(1.0,0.0);glVertex3f(-1.0,-1.0,1.0);

       //第二个

       glNormal3f(0.0,0.0,1.0);

       glTexCoord2f(0.0,0.0);glVertex3f(-1.0,-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);

       glTexCoord2f(0.0,1.0);glVertex3f(-1.0,1.0,1.0);

       //第三个

       glNormal3f(0.0,0.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);

       glTexCoord2f(0.0,1.0);glVertex3f(1.0,1.0,-1.0);

       glTexCoord2f(0.0,0.0);glVertex3f(1.0,-1.0,-1.0);

       //第四个

       glNormal3f(1.0,0.0,0.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);

       glTexCoord2f(0.0,1.0);glVertex3f(1.0,1.0,1.0);

       glTexCoord2f(0.0,0.0);glVertex3f(1.0,-1.0,1.0);

       //第五个

       glNormal3f(-1.0,0.0,0.0);

       glTexCoord2f(0.0,0.0);glVertex3f(-1.0,-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);

       glTexCoord2f(0.0,1.0);glVertex3f(-1.0,1.0,-1.0);

 

       glEnd();

       glEndList();//完成了一个显示列表

       top = box + 1;//上一个显示列表的指针加1,得到第二个显示列表,列表指针为top

       glNewList(top,GL_COMPILE);

       glBegin(GL_QUADS);

       glNormal3f(0.0,1.0,0.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);

       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();

       glEndList();//第二个显示列表完毕

 

       tri = top +1;

       glNewList(tri,GL_COMPILE);

       glBegin(GL_TRIANGLES);

        //第一面

       glNormal3f(0.0,1.0,0.0);

       glColor3f(1.0,0.0,0.0);glVertex3f(0.0,1.0,0.0);

       glColor3f(0.0,1.0,0.0);glVertex3f(-1.0,-1.0,1.0);

       glColor3f(1.0,0.0,1.0);glVertex3f(1.0,-1.0,1.0);

       //第二面

       glNormal3f(0.0,1.0,0.0);

       glColor3f(1.0,0.0,0.0);glVertex3f(0.0,1.0,0.0);

       glColor3f(0.0,0.0,1.0);glVertex3f(1.0,-1.0,1.0);

       glColor3f(0.0,1.0,0.0);glVertex3f(1.0,-1.0,-1.0);

       //第三面

       glNormal3f(0.0,1.0,0.0);

       glColor3f(1.0,0.0,0.0);glVertex3f(0.0,1.0,0.0);

       glColor3f(0.0,1.0,0.0);glVertex3f(1.0,-1.0,-1.0);

       glColor3f(0.0,0.0,1.0);glVertex3f(-1.0,-1.0,-1.0);

       //第四面

       glNormal3f(0.0,1.0,0.0);

       glColor3f(1.0,0.0,0.0);glVertex3f(0.0,1.0,0.0);

       glColor3f(0.0,0.0,1.0);glVertex3f(-1.0,-1.0,-1.0);

       glColor3f(0.0,1.0,0.0);glVertex3f(-1.0,-1.0,1.0);

       glEnd();

       glEndList();

}

void glutttt::paintGL()

{

       glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存

       glBindTexture(GL_TEXTURE_2D,texture[filter]);//绑定纹理

       qobj = gluNewQuadric();

       gluQuadricDrawStyle(qobj,GLU_LINE);

       gluQuadricNormals(qobj,GLU_SMOOTH);

 

       switch(obj)

       {

       case 0:

              drawFlag();//旗

              break;

       case 1:

              drawList();//盒子列表

              break;

       case 2:

              glLoadIdentity();

              glTranslatef(0,0,zoom);//

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              auxWireDodecahedron(2.0);

              break;

       case 3:

              glLoadIdentity();

              glTranslatef(0,0,zoom);//球

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutSolidSphere(2,64,64);//实心

              break;

       case 4:

              glLoadIdentity();

              glTranslatef(0,0,zoom);//球

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutWireSphere(2,64,64);//网状

              break;

       case 5:

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              gluCylinder(qobj,2.0,2.0,4.0,100,5);//圆柱

              break;

       case 6:

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              gluCylinder(qobj,2.0,0.0,4.0,100,5);//圆锥

              break;

       case 7:

              glLoadIdentity();

              glTranslatef(0,0,zoom);//圆盘

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              gluDisk(qobj,1.0,2.0,1000,1);      

              break;

 

       case 8:

              glLoadIdentity();

              glTranslatef(0,0,zoom);//绘制部分圆盘

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              part1 += p1;

              part2 += p2;

              if (part1>359)

              {

                     p1 = 0;

                     part1 = 0;

                     p2 = 1;

                     part2 = 0;

              }

              if (part2>359)

              {

                     p1 = 1;

                     p2 =0;

              }

              gluPartialDisk(qobj,1.0,3.0,1000,1,part1,part2-part1);

              break;

 

       case 9:    //网状茶壶

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutWireTeapot(3.0);

              break;

       case 10:    //实心茶壶

              glLoadIdentity();

              glTranslatef(1.5,-2.5,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutSolidTeapot(3.0);

              break;

       case 11:

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutSolidCone(2,4,64,64);//实心圆锥

              break;

       case 12:

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutSolidCube(3.0);//实心立方体

              break;

       case 13:

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutWireDodecahedron();//十二面体

              break;

       case 14:

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutWireIcosahedron();//二十面体

              break;

       case 15:

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutSolidOctahedron();//八面体

              break;

       case 16:

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutSolidTetrahedron();//四面体

              break;

       case 17:

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              glutSolidTorus(1.5,2.0,64,64);//圆环

              break;

       case 18:          //画四棱锥列表

              glLoadIdentity();

              glTranslatef(0,0,zoom);

              glRotatef(xrot,1.0,0.0,0.0);

              glRotatef(yrot,0.0,1.0,0.0);

              glRotatef(zrot,0.0,0.0,1.0);

              for (yLoop = 1;yLoop<6;yLoop++)//改变y轴位置

              {

                     for (xLoop = 0;xLoop

                     {

                            glLoadIdentity();

                            glTranslatef(1.4+(float(xLoop)*2.8)-(float(yLoop)*1.4),((6.0-(float(yLoop))*2.4)+2.0),zoom);

                            glRotatef(45.0-(2.0*yLoop)+xrot,1.0,0.0,0.0);

                            glRotatef(45.0+yrot,0.0,1.0,0.0);

                            glCallList(tri);

                     }

              }

              break;

       }

       xrot += 1.0;

       yrot += 0.5;

       zrot += 0.3;

}

//画列表

void glutttt::drawList()

{

       glLoadIdentity();

       glRotatef(xrot,1.0,0.0,0.0);

       glRotatef(yrot,0.0,1.0,0.0);

       glRotatef(zrot,0.0,0.0,1.0);

       for (yLoop = 1;yLoop<6;yLoop++)//改变y轴位置

       {

              for (xLoop = 0;xLoop

              {

                     glLoadIdentity();

                     glTranslatef(1.4+(float(xLoop)*2.8)-(float(yLoop)*1.4),((6.0-(float(yLoop))*2.4)+2.0),zoom);

                     glRotatef(45.0-(2.0*yLoop)+xrot,1.0,0.0,0.0);

                     glRotatef(45.0+yrot,0.0,1.0,0.0);

                     glColor3fv(boxcol[yLoop-1]);

                     glCallList(box);

                     glColor3fv(topcol[yLoop-1]);

                     glCallList(top);

              }

       }

}

//画旗子

void glutttt::drawFlag()

{

       int x,y;

       float float_x,float_y,float_xb,float_yb;

       glLoadIdentity();

       glTranslatef(0,0,zoom);

       glRotatef(xrot,1.0,0.0,0.0);

       glRotatef(yrot,0.0,1.0,0.0);

       glRotatef(zrot,0.0,0.0,1.0);

       glBegin(GL_QUADS);

       for (x=0;x<44;x++)

       {

              for (y=0;y<44;y++)

              {

                     float_x = float(x)/44.0;

                     float_y = float(y)/44.0;

                     float_xb = float(x+1)/44.0;

                     float_yb = float(y+1)/44.0;

 

                     //左下

                     glTexCoord2f(float_x,float_y);

                     glVertex3f(points[x][y][0],points[x][y][1],points[x][y][2]);

                     //左上

                     glTexCoord2f(float_x,float_yb);

                     glVertex3f(points[x][y+1][0],points[x][y+1][1],points[x][y+1][2]);

                     //右上

                     glTexCoord2f(float_xb,float_yb);

                     glVertex3f(points[x+1][y+1][0],points[x+1][y+1][1],points[x+1][y+1][2]);

                     //右下

                     glTexCoord2f(float_xb,float_y);

                     glVertex3f(points[x+1][y][0],points[x+1][y][1],points[x+1][y][2]);

              }

       }

       glEnd();

 

       if (wiggle_count == 2)

       {

              for (y=0;y<45;y++)

              {

                     hold = points[0][y][2];

                     for (x=0;x<44;x++)

                     {

                            points[x][y][2] = points[x+1][y][2];

                     }

                     points[44][y][2] = hold;

              }

              wiggle_count = 0;

       }

       wiggle_count++;

}

//为透视图设置屏幕,创建一个现实外观的场景

void glutttt::resizeGL(int w, int h)

{

       if (h==0)

       {

              h=1;

       }//防止高为0

       glViewport(0,0,(GLint)w,(GLint)h);//重置当前的视口

       glMatrixMode(GL_PROJECTION);//选择投影矩阵

       glLoadIdentity();//重置投影矩阵

       gluPerspective(45.0,(GLfloat)w/(GLfloat)h,0.1,100.0);//建立透视投影矩阵

       glColor4f(1.0,1.0,1.0,0.5);

       glBlendFunc(GL_SRC_ALPHA,GL_ONE);

       glMatrixMode(GL_MODELVIEW);//选择模型观察矩阵

       glLoadIdentity();//重置模型观察矩阵

}

 

//载入纹理

void glutttt::loadGLTextures()

{

       QImage tex1,tex2,tex3,tex4,buf;

       if (!buf.load("./1.jpg"))

       {

              qWarning("cannot open image...");

              QImage dummy(128,128,QImage::Format_ARGB32);

              dummy.fill(Qt::green);

              buf = dummy;//如果载入不成功,自动生成128*128的32位绿色图片

       }

       tex1 = QGLWidget::convertToGLFormat(buf);//QGLWidget提供的专门转换图片的静态函数

       glGenTextures(4,&texture[0]);//创建4个纹理

       glBindTexture(GL_TEXTURE_2D,texture[0]);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

       glTexImage2D(GL_TEXTURE_2D,0,3,tex1.width(),tex1.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,tex1.bits());

 

       if (!buf.load("./2.jpg"))

       {

              qWarning("cannot open image...");

              QImage dummy(128,128,QImage::Format_ARGB32);

              dummy.fill(Qt::green);

              buf = dummy;

       }

       tex2 = QGLWidget::convertToGLFormat(buf);

       glBindTexture(GL_TEXTURE_2D,texture[1]);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

       glTexImage2D(GL_TEXTURE_2D,0,3,tex1.width(),tex2.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,tex2.bits());

 

       if (!buf.load("./3.bmp"))

       {

              qWarning("cannot open image...");

              QImage dummy(128,128,QImage::Format_ARGB32);

              dummy.fill(Qt::green);

              buf = dummy;

       }

       tex3 = QGLWidget::convertToGLFormat(buf);

       glBindTexture(GL_TEXTURE_2D,texture[2]);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

       glTexImage2D(GL_TEXTURE_2D,0,3,tex3.width(),tex3.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,tex3.bits());

 

       if (!buf.load("./4.jpg"))

       {

              qWarning("cannot open image...");

              QImage dummy(128,128,QImage::Format_ARGB32);

              dummy.fill(Qt::green);

              buf = dummy;

       }

       tex4 = QGLWidget::convertToGLFormat(buf);

       glBindTexture(GL_TEXTURE_2D,texture[3]);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

       glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);

      gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGB,tex4.width(),tex4.height(),GL_RGBA,GL_UNSIGNED_BYTE,tex4.bits());

 

}

glutttt::~glutttt()

{

}

//重绘

void glutttt::timerEvent(QTimerEvent *)

{

       updateGL();

}

//鼠标单击事件

void glutttt::mousePressEvent(QMouseEvent *e)

{

       lastPos = e->pos();

}

//鼠标拖动事件

void glutttt::mouseMoveEvent(QMouseEvent *e)

{

       GLfloat dx = GLfloat(e->x()-lastPos.x())/width();

       GLfloat dy = GLfloat(e->y()-lastPos.y())/height();

       if (e->buttons()&Qt::LeftButton)

       {

              xrot += dy*180;

              yrot += dx*180;

              updateGL();

       }

       else if (e->buttons()&Qt::RightButton)

       {

              xrot += dy*180;

              yrot += dx*180;

              updateGL();

       }

}

//鼠标释放事件

void glutttt::mouseReleaseEvent(QMouseEvent *e)

{

       lastPos = e->pos();

}

//滚轮事件

void glutttt::wheelEvent(QWheelEvent *e)

{

       GLfloat zValue = e->delta();

       zoom -= zValue*0.001;

       if (zoom>1.0)

       {

              zoom = 1.0;

       }

       updateGL();

}

 

//******************************mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

 

#include

#include "ui_mainwindow.h"

#include "glutttt.h"

#include

#include

 

class mainWindow : public QMainWindow

{

       Q_OBJECT

 

public:

       mainWindow(QWidget *parent = 0);

       ~mainWindow();

 

       void keyPressEvent(QKeyEvent *e);//鼠标按下事件处理函数

 

private:

       Ui::mainWindow ui;

       enum{numRow = 3,numColumn = 3};

       glutttt *glWidgets[numRow][numColumn];

       glutttt *currentGLWidget;

       int flag;

 

       void setCurrentGlWidget();

 

};

 

#endif // MAINWINDOW_H

 

// ***********************mainwindow.cpp

 

#include "mainwindow.h"

#include

 

 

mainWindow::mainWindow(QWidget *parent)

       : QMainWindow(parent)

{

       ui.setupUi(this);

       QWidget *widget = new QWidget;

       this->setCentralWidget(widget);

       QGridLayout *mainlayout = new QGridLayout(widget);

       for (int i=0;i

       {

              for (int j=0;j

              {

                     glWidgets[i][j] =  new glutttt;

                     mainlayout->addWidget(glWidgets[i][j],i,j);

              }

       }

       flag = 0;

       resize(1000,800);

       currentGLWidget = new glutttt;

       currentGLWidget = glWidgets[0][0];

}

 

mainWindow::~mainWindow()

{

 

}

 

void mainWindow::setCurrentGlWidget()

{

       switch(flag)

       {

       case 0:

              currentGLWidget = glWidgets[0][0];

              break;

       case 1:

              currentGLWidget = glWidgets[0][1];

              break;

       case 2:

              currentGLWidget = glWidgets[0][2];

              break;

       case 3:

              currentGLWidget = glWidgets[1][0];

              break;

       case 4:

              currentGLWidget = glWidgets[1][1];

              break;

       case 5:

              currentGLWidget = glWidgets[1][2];

              break;

       case 6:

              currentGLWidget = glWidgets[2][0];

              break;

       case 7:

              currentGLWidget = glWidgets[2][1];

              break;

       case 8:

              currentGLWidget = glWidgets[2][2];

              break;

       }

}

//键盘事件

void mainWindow::keyPressEvent(QKeyEvent *e)

{

       switch(e->key())

       {

       case Qt::Key_Alt:

              flag+= 1;

              if (flag>8)

              {

                     flag = 0;

              }

              setCurrentGlWidget();

              break;

       case Qt::Key_F2:    //全屏

              currentGLWidget->fullScreen = !currentGLWidget->fullScreen;

              if (currentGLWidget->fullScreen)

              {

                     currentGLWidget->showFullScreen();

              }

              else

                     currentGLWidget->showNormal();

              currentGLWidget->updateGL();

              break;

       case Qt::Key_Left:  //x轴旋转

              currentGLWidget->xrot += 5.0;

              currentGLWidget->updateGL();

              break;

       case Qt::Key_Right:       //y轴旋转

              currentGLWidget->yrot += 5.0;

              currentGLWidget->updateGL();

              break;

       case Qt::Key_Z:             //z轴旋转

              currentGLWidget->zrot += 5.0;

              currentGLWidget->updateGL();

              break;

       case Qt::Key_Up:    //缩小视距

              currentGLWidget->zoom += 0.5;

              currentGLWidget->updateGL();

              break;

       case Qt::Key_Down:      //增大视距

              currentGLWidget->zoom -= 0.5;

              currentGLWidget->updateGL();

              break;

       case Qt::Key_L:             //开启灯光

              currentGLWidget->light = !currentGLWidget->light;

              if (currentGLWidget->light)

              {

                     glEnable(GL_LIGHTING);

              }

              else

              {

                     glDisable(GL_LIGHTING);

              }

              currentGLWidget->updateGL();

              break;

       case Qt::Key_G:            //开启大雾效果

              currentGLWidget->fogFilter += 1;

              glEnable(GL_FOG);

              if (currentGLWidget->fogFilter>3)

              {

                     currentGLWidget->fogFilter = 0;

              }

              if (currentGLWidget->fogFilter == 3)

              {

                     glDisable(GL_FOG);

              }

              currentGLWidget->updateGL();

              break;

       case Qt::Key_B:             //开启融合透视效果

              currentGLWidget->blend = !currentGLWidget->blend;

              if (currentGLWidget->blend)

              {

                     glEnable(GL_BLEND);

                     glDisable(GL_DEPTH_TEST);

              }

              else

              {

                     glDisable(GL_BLEND);

                     glEnable(GL_DEPTH_TEST);

              }

              currentGLWidget->updateGL();

              break;

       case Qt::Key_F:             //切换纹理

              currentGLWidget->filter += 1;

              if (currentGLWidget->filter>3)

              {

                     currentGLWidget->filter = 0;

              }

              currentGLWidget->updateGL();

              break;

       case Qt::Key_Space:             //选择事件

              currentGLWidget->obj++;

              currentGLWidget->obj = currentGLWidget->obj%19;

              currentGLWidget->updateGL();

              break;

       }

}

 

///********************Main,cpp

#include

#include

#include

 

#include "glutttt.h"

#include

#include "mainwindow.h"

 

int main(int argc, char *argv[])

{

       QApplication a(argc, argv);

       mainWindow w;

       w.show();

       return a.exec();

}

你可能感兴趣的:(C++,Qt)