一、    提要


    在前面的一篇文章我们已经配置好了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