由于要在OpenGL中实现放大缩小旋转和移动的效果,故要重写鼠标事件
放大缩小
重写void wheelEvent(QWheelEvent *event)函数
void zScale(float dz)函数用来实现放大和缩小的比例
定义一个放大缩小的倍数属性GLfloat zscale,需要初始化为1
void wheelEvent(QWheelEvent *event)
{
int qwheel = event->delta(); // positive when wheel up, delta +/- 120 when wheel +/- 1
zScale(qwheel*2.0);
update();
}
event->delta()的值表示滚轮前进还是后退,前进为正值,一般为120,update用来刷新绘图
void zScale(float dz)
{
if(zscale-dz*1e-3>0)
zscale-=dz*1e-3;
update();
}
然后在绘图函数OpenGL绘图函数paintGL()中调用glScalef(zscale,zscale,zscale),实现放大缩小的效果
旋转图形和移动图形
旋转图形:点击鼠标来进行3D图形的旋转,故需要重写
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
一个是用来获取鼠标点击的,一般用他来得到初始点击的位置,因为3D图形的移动还有旋转是通过两次鼠标事件的差值来进行计算的,故需要用两个变量来保存当前鼠标的坐标值和上一次鼠标的坐标值,如果第一次进入界面点击而没有获取鼠标的值,会有一个闪烁的现象
一个是鼠标移动的函数
void mousePressEvent(QMouseEvent *event)
{
setFocus();
if(event->buttons() & Qt::LeftButton)
{
}
else if(event->buttons() & Qt::RightButton)
{
}
else if(event->buttons() & Qt::MidButton){
}
lastPos = event->pos();
update();
}
void mouseMoveEvent(QMouseEvent *event)
{
QPoint qPoint = event->pos();// - lastPos; // mouse move right x+, down y+
if(event->buttons() & Qt::LeftButton)
{
xyRotate(qPoint.x(), qPoint.y());
}
else if(event->buttons() & Qt::RightButton)
{
//xyTranslate(qPoint.x(), qPoint.y());
}
else if(event->buttons() & Qt::MidButton)
{
xyTranslate(qPoint.x(), qPoint.y());
}
lastPos = event->pos();//Update the mouse coordinate
update();
}
xyRotate函数用来实现旋转,xyTranslate函数用来实现平移
void MYOpenGL::xyRotate(int dx, int dy)//旋转
{
currPos.setX(dx);
currPos.setY(dy);
dx-=lastPos.x();
dy-=lastPos.y();
if(dx < 4.0&&dx>-4 && dy < 4.0&&dy>-4)
{
return;
}
horizonAngle+=dx/6.0;
//if(verticalAngle+dy <89 && verticalAngle+dy >-89)
verticalAngle+=dy/6.0;
lastPos=currPos;//Update the mouse coordinate
}
horizonAngle表示水平旋转的角度,verticalAngle垂直旋转的角度,他们都是类的中的属性,需要事先定义并初始化
然后在paintGL()函数中使用OpenGL自带的旋转函数
glRotatef(horizonAngle-45,0,0,1);
glRotatef(-verticalAngle+m_cursite.asite,1,0,0);
本次代码是实际项目中的,要根据需要调整具体是旋转哪一个轴,0,0,1表示的旋转的Z轴
对于平移
void xyTranslate(int dx, int dy)
{
currPos.setX(dx);
currPos.setY(dy);
dx-=lastPos.x();
dy-=lastPos.y();
if(dx < 4.0&&dx>-4 && dy < 4.0&&dy>-4)
{
return;
}
horizonTran+=dx/4.0;
verticalTran+=dy/4.0;
lastPos=currPos;
}
horizonTran和verticalTran同样需要实现定义,在paintGL()函数中
glTranslatef(-horizonTran,0,-verticalTran);
此参数分别表示原本坐标系要分别移动x、y、z的距离
Tips:
由于此次的项目是管材项目,客户那边初始时需要正轴测管材,则X轴正方向朝左,Y轴正方向朝用户,Z轴正方向朝上,故观察时
gluLookAt(0,EYEY_SCALE*g_W, EYEZ_SCALE*g_H,//观察点
0,0,0,//中心点
0.0,0.0,1.0);
后面3个参数表示哪一个轴朝上,具体为什么Z轴设置为朝上 整个图形就按X轴正方向朝左,Y轴正方向朝用户,Z轴正方向朝上排放,我也不太清除