OpenGL实现二维图的缩放

严格说来,OpenGL只在3维空间绘制,glVertex2f之类的函数,是默认z = 0的。那么如何实现二维图的缩放呢?先来介绍3个知识点。

1)OpenGL的坐标系:X轴从左向右是正方向,Y轴从下到上是正方向,Z轴从屏幕指向操作者是正方向。绘制物体时,物体的坐标就是在这个坐标系里定义的。

2)gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)定义了“取景”范围:

取景区域是一个前窄后宽,类似金字塔形,但没有尖的区域。

fovy是垂直方向上金字塔的2个面的夹角。aspect是金字塔的截面的长宽比。zNear是金字塔的“尖”(其实尖不在取景范围内)到比较小的截面的距离;zFar是“尖”到比较大的截面的距离。有了这四个量,金字塔的形状就确定了。更详细的解释见http://www.cnblogs.com/chengmin/archive/2011/09/12/2174004.html

OpenGL实现二维图的缩放_第1张图片


但是金子塔的位置怎么确定呢?塔尖的位置就在观察者那里。

3)观察者的位置由gluLookAt(GLdoble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz)决定。 eyex,eyey,eyez决定了观察者的位置。观察者的观察方向是从坐标(eyex,eyey,eyez)指向坐标(centerx,centery,centerz)的矢量。最后3个变量也构成一个矢量,代表观察者眼中的“正上方”。

我们可以通过设置gluPerspective函数中fovy的值实现二维物体的缩放。如果fovy大了,观察者看到的区域也就变大。相对而言,二维物体在观察者眼中(也就是我们的窗口,opengl窗口里显示的就是观察者看到的)占得比例就小了。由于我们的窗口大小不变,二维物体就显得缩小了。反之,fovy小,就会产生放大效果。

看下面代码,通过鼠标实现缩放:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 

class MainWindow : public QGLWidget
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    int           m_iWidth;
    int           m_iHeight;
    int           m_iMag;
private:

protected:
    virtual void initializeGL();
    virtual void paintGL();
    virtual void resizeGL(int, int);

    virtual void wheelEvent(QWheelEvent *);
};

#endif // MAINWINDOW_H

#include "mainwindow.h"
#include 

MainWindow::MainWindow(QWidget *parent) :
    QGLWidget(parent)

{

}

MainWindow::~MainWindow()
{

}

void MainWindow::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 MainWindow::initializeGL()
{
    glClearColor(0.0, 1.0, 1.0, 0);
    m_iMag = 1;
}

void MainWindow::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 MainWindow::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(0.0 , 0.0, 50.0, 0.0, 0.0, 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();
}

运行结果:

OpenGL实现二维图的缩放_第2张图片


滚动鼠标后:

OpenGL实现二维图的缩放_第3张图片


这是视界变化造成的缩放效果。

你可能感兴趣的:(qt,opengl,opengl)