在前面的一篇文章我们已经配置好了opengl的编程环境,今天要做的就是搭建一个Qt的编程框架,方便后面的学习。这一节会涉及到一些OpenGL的基础方法,多用手册和搜索引擎去理解。
二、 框架结构
项目的结构如下图。
主要的思路是:mainwindow类用来处理程序的逻辑和交互,nehewidget是继承QGLWidget的,用来绘制Opengl。在.pro文件中一定要加入QT+= opengl,还有喔没有使用QtCreater的ui编辑功能。
QGLWidget中最重要的三个方法是:
paintGL() -渲染OpenGL场景,当窗口需要刷新的时候就会被调用 .
resizeGL() -设置OpenGL的视口和一些属性,当窗口改变大小和窗口被创建的时候被调用。resizeGL()在处理完后会自动刷新屏幕。
initializeGL() -设置OpenGL的渲染环境,定义显示选项,当resizeGL() 或 paintGL()第一次运行的时候被调用。
二、 框架实现
main.cpp没有做任何改动。
- #include <QtGui/QApplication>
- #include "mainwindow.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- MainWindow w;
- w.show();
- return a.exec();
- }
mainwindow.h
将nehewidget作为自己的一个私有变量,并定义键盘事件。
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QtGui/QMainWindow>
- #include <QKeyEvent>
- #include "nehewidget.h"
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- MainWindow(QWidget *parent = 0);
- ~MainWindow();
- protected:
- bool fullscreen;
- //处理键盘事件
- void keyPressEvent( QKeyEvent *e );
- private:
- NeHeWidget *neheWidget ;
- };
- #endif // MAINWINDOW_H
mainwindow.cpp
- #include "mainwindow.h"
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- {
- neheWidget = new NeHeWidget();
- fullscreen = true;
- setGeometry(100,100,1000,768);
- setWindowTitle(tr("NeHe's OpenGL Framework"));
- setCentralWidget(neheWidget);
- }
- MainWindow::~MainWindow()
- {
- }
- void MainWindow::keyPressEvent(QKeyEvent *e)
- {
- switch ( e->key() )
- {
- case Qt::Key_F2:
- fullscreen = !fullscreen;
- if ( fullscreen )
- {
- showFullScreen();
- }
- else
- {
- showNormal();
- }
- neheWidget->updateGL();
- break;
- case Qt::Key_Escape:
- close();
- break;
- }
- }
nehewidget.h
- #ifndef NEHEWIDGET_H
- #define NEHEWIDGET_H
- #include <QGLWidget>
- #include <QtGui>
- #include <QtOpenGL>
- class NeHeWidget : public QGLWidget
- {
- Q_OBJECT
- public:
- explicit NeHeWidget(QWidget *parent = 0);
- ~NeHeWidget();
- protected:
- //设置渲染环境
- void initializeGL();
- //绘制窗口
- void paintGL();
- //响应窗口的大小变化
- void resizeGL( int width, int height );
- };
- #endif // NEHEWIDGET_H
nehewidget.cpp
- #include "nehewidget.h"
- NeHeWidget::NeHeWidget(QWidget *parent) :
- QGLWidget(parent)
- {
- }
- NeHeWidget::~NeHeWidget()
- {}
- void NeHeWidget::initializeGL()
- {
- // 启用阴影平滑
- glShadeModel( GL_SMOOTH );
- // 黑色背景
- glClearColor( 0.0, 0.0, 0.0, 0.0 );
- // 设置深度缓存
- glClearDepth( 1.0 );
- // 启用深度测试
- glEnable( GL_DEPTH_TEST );
- // 所作深度测试的类型
- glDepthFunc( GL_LEQUAL );
- // 告诉系统对透视进行修正
- glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
- }
- void NeHeWidget::paintGL()
- {
- // 清除屏幕和深度缓存
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- glLoadIdentity();
- //坐标转移
- glTranslatef(-1.5f,0.0f,-6.0f);
- //设置颜色
- glColor3f( 1.0, 1.0, 1.0 );
- //绘制一个正方形
- glBegin( GL_QUADS );
- glVertex3f( -1.0, 1.0, 0.0 );
- glVertex3f( 1.0, 1.0, 0.0 );
- glVertex3f( 1.0, -1.0, 0.0 );
- glVertex3f( -1.0, -1.0, 0.0 );
- glEnd();
- }
- // 重置OpenGL窗口大小
- void NeHeWidget::resizeGL(int width, int height)
- {
- // 防止窗口大小变为0
- if ( height == 0 )
- {
- height = 1;
- }
- // 重置当前的视口
- 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();
- }
三、程序说明
F2用于全屏显示,ESC退出,程序绘制了一个正方形,且改变窗口大小,图形会按比例改变。
OpenGL的一些初始化函数就一一解释了,注释里面有一些信息,以后遇到的话再仔细解释。
框架搭建好之后学习我们主要去修改void NeHeWidget::paintGL()就可以了实现相应的效果了。
四.参考资料
1. 《 OpenGL Reference Manual 》, OpenGL 参考手册
2. 《 OpenGL 编程指南》(《 OpenGL Programming Guide 》), Dave Shreiner , Mason Woo , Jackie Neider , Tom Davis 著,徐波译,机械工业出版社
3. 《win32 OpenGL编程 》 一个大牛的博客 http://blog.csdn.net/vagrxie/article/category/628716/3