环境:Qt4.7.3 + VS2008
效果图:
//*************** 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(); }