在前面的博客《OpenGL实现二维图的缩放》中,我提到了gluLookAt的作用是定义观察者的位置和视线方向。在本文中,我们正好利用这个功能来实现二维图的平移。
#ifndef WIDGET_H
#define WIDGET_H
#include <QGLWidget>
#include <QWheelEvent>
#include <QMouseEvent>
class Widget : public QGLWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
int m_iWidth;
int m_iHeight;
float m_fXOffset;
float m_fYOffset;
float m_fPrevXPos;
float m_fPrevYPos;
int m_iXPos;
int m_iYPos;
bool m_bMoved;
int m_iMag;
private:
protected:
virtual void initializeGL();
virtual void paintGL();
virtual void resizeGL(int, int);
virtual void wheelEvent(QWheelEvent *);
virtual void mouseMoveEvent(QMouseEvent *);
virtual void mousePressEvent(QMouseEvent *);
virtual void mouseReleaseEvent(QMouseEvent *);
};
#endif // WIDGET_H
#include "widget.h"
#include <GL/glu.h>
Widget::Widget(QWidget *parent) :
QGLWidget(parent)
{
setMouseTracking(false);
m_fPrevXPos = m_fPrevYPos = 0.0;
m_fXOffset = m_fYOffset = 0.0;
m_bMoved = false;
}
Widget::~Widget()
{
}
void Widget::wheelEvent(QWheelEvent *e)
{
QPoint qpMag = e->angleDelta();
int iMag = qpMag.y();
bool bUpdate = false;
if(iMag > 0)
{
if(m_iMag < 8)
{
m_iMag *= 2;
bUpdate = true;
}
}
if(iMag < 0)
{
if(m_iMag > 1)
{
m_iMag /= 2;
bUpdate = true;
}
}
if(bUpdate)
{
updateGL();
}
}
void Widget::initializeGL()
{
glClearColor(0.0, 1.0, 1.0, 0);
m_iMag = 1;
}
void Widget::resizeGL(int w, int h)
{
if(w > 0 && h >0)
{
glViewport(0, 0, (GLint)w, (GLint)h);//这句话把显示的范围跟glWindow范围划了等号
m_iWidth = w;
m_iHeight = h;
}
}
void Widget::paintGL()
{
//clear放在初始化里面会造成闪烁
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(10.0 * m_iMag, m_iWidth / m_iHeight, -8.0, 8.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(m_fPrevXPos + m_fXOffset * 0.01, m_fPrevYPos + m_fYOffset * 0.01, 50.0,
m_fPrevXPos + m_fXOffset * 0.01, m_fPrevYPos + m_fYOffset * 0.01, 0.0,
0.0, 1.0, 0.0);
glBegin(GL_QUADS);
glVertex2f(-0.5, -0.5);
glVertex2f(0.5, -0.5);
glVertex2f(0.5, 0.5);
glVertex2f(-0.5, 0.5);
glEnd();
}
void Widget::mouseMoveEvent(QMouseEvent *e)
{
if(m_bMoved)
{
m_fXOffset = m_iXPos - e->x();
m_fYOffset = e->y() - m_iYPos;//widget对Y方向的定义和opengl坐标系相反
updateGL();
}
}
void Widget::mouseReleaseEvent(QMouseEvent *e)
{
Q_UNUSED(e);
m_fPrevXPos += m_fXOffset * 0.01;
m_fPrevYPos += m_fYOffset * 0.01;
m_fXOffset = m_fYOffset = 0.0;
m_bMoved = false;
}
void Widget::mousePressEvent(QMouseEvent *e)
{
m_iXPos = e->x();
m_iYPos = e->y();
m_bMoved = true;
}
运行程序,可见白色正方形随着鼠标拖动而移动