为了满足高级绘图的需求,在Qt中支持OpenGL接口和矢量图形格式SVG。使用OpenGL可以完成3D绘图,SVG模块则可以绘制XML格式的矢量图形SVG。Qt还支持直接操作显存的QGLFramebufferObject对象。
1、OpenGL是最开始在SGI公司推出的3D绘图编程接口,OpenGL具有绘制三维图形的各种函数,但不包括窗口系统或处理用户输入的函数。为了在Qt中使用OpenGL,Qt提供了OpenGL模块。在Qt中使用OpenGL的途径是使用QGLWidget(在qt5中用QOpenGLWidget代替)类,并使用OpenGL API进行绘图。要在QT程序中使用OpenGL API,需要包括头文件:
<pre name="code" class="cpp">#include<QtOpenGL>
同时在qmake的工程中加入
<pre name="code" class="cpp">QT += opengl
2、创建OpenGL窗口
创建OpenGL应用程序通常要从QGLWidget类继承出自己的类。QGLWidget类从Qwidget类继承,提供了在Qt应用程序中显示OpenGL图形的能力。QGLWidget类提供了三个虚函数完成openGL的绘图任务,initializeGL()完成OpenGL环境的初始化,paintGL()绘制OpenGL图形,resizeGL()在窗口变化时运行。下面建立一个简单的OpenGL程序。
首先定义MyGLWidget类,头文件如下所示:
#ifndef MYGL_H_
#define MYGL_H_
#include <QtGui>
#include <QtOpenGL>
class MyGLWidget : public QGLWidget
{
Q_OBJECT
public:
MyGLWidget(QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0);
~MyGLWidget();
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
void mouseDoubleClickEvent( QMouseEvent * event );
private:
GLfloat Point[5][3];
};
#endif /*MYGL_H_*/
实现文件如下:
#include <QtGui>
#include <QtOpenGL>
#include <math.h>
#include "mygl.h"
#include<gl/glu.h>
const GLfloat PI = 3.1415926536f;
MyGLWidget::MyGLWidget(QWidget * parent, const QGLWidget * shareWidget, Qt::WindowFlags f)
{
setMinimumSize(320,240);
resize(640,480);
setWindowTitle(tr("第一个OpenGL程序"));
short angle = 18;
for(short i=0; i<5; i++) {
Point[i][0] = cos(angle * PI/180);
Point[i][1] = sin(angle * PI/180);
Point[i][2] = 0.0;
angle += 72;
}
}
MyGLWidget::~MyGLWidget()
{
}
//重写初始化的虚函数
void MyGLWidget::initializeGL()
{
glShadeModel(GL_SMOOTH);//设置阴影平滑模式
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//改变窗口的背景颜色
glClearDepth(1.0);//设置深度缓存
glEnable(GL_DEPTH_TEST);//允许深度测试
glDepthFunc(GL_LEQUAL);//设置深度测试类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//进行透视校正
glEnableClientState(GL_VERTEX_ARRAY);//启用数组
glVertexPointer(3, GL_FLOAT, 0, Point);//指定数组的数据
}
//重写绘制的虚函数
void MyGLWidget::paintGL()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );//清除屏幕及深度缓冲区
glLoadIdentity();//装入单位矩阵
glTranslatef( -1.5, 0.0, -6.0 );//将坐标原点移动到( -1.5, 0.0, -6.0 )
glBegin( GL_TRIANGLES );//绘制三角形
glVertex3f( 0.0, 1.0, 0.0 );//提供三角形顶点
glVertex3f( -1.0, -1.0, 0.0 );
glVertex3f( 1.0, -1.0, 0.0 );
glEnd();//绘制结束
glTranslatef( 3.0, 0.0, 0.0 );
glBegin(GL_LINE_LOOP);
glArrayElement(1);
glArrayElement(4);
glArrayElement(2);
glArrayElement(0);
glArrayElement(3);
glEnd();
/*glBegin(GL_LINE_LOOP);
glVertex3f(Point[1][0], Point[1][1], Point[1][2]);
glVertex3f(Point[4][0], Point[4][1], Point[4][2]);
glVertex3f(Point[2][0], Point[2][1], Point[2][2]);
glVertex3f(Point[0][0], Point[0][1], Point[0][2]);
glVertex3f(Point[3][0], Point[3][1], Point[3][2]);
glEnd();*/
}
//窗口大小发生变化时调用
void MyGLWidget::resizeGL(int width, int height)
{
glViewport( 0, 0, (GLint)width, (GLint)height );
glMatrixMode( GL_PROJECTION );//指明接下来的函数将影响投影矩阵。投影矩阵负责为场景增加透视
glLoadIdentity();//为场景设置透视图
gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );
glMatrixMode( GL_MODELVIEW );//指明任何新的变换将会影响模型视图矩阵。模型视图矩中存放物体信息
glLoadIdentity();
}
//实现鼠标双击窗口客户区实现全屏和窗口显示切换
void MyGLWidget::mouseDoubleClickEvent( QMouseEvent * event )
{
if(windowState() & Qt::WindowFullScreen)
showNormal();
else
showFullScreen();
}
最后一步是实现main.cpp
#include <QtGui>
#include "mygl.h"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyGLWidget myglWidget;
myglWidget.show();
return app.exec();
}
运行结果: