严格说来,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
但是金子塔的位置怎么确定呢?塔尖的位置就在观察者那里。
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();
}
滚动鼠标后:
这是视界变化造成的缩放效果。