Qt上的OpenGL 编程(2)动手搭建Qt上的OpenGL编程框架

Qt下的OpenGL 编程(2)动手搭建Qt下的OpenGL编程框架

一、    提要


    在前面的一篇文章我们已经配置好了opengl的编程环境,今天要做的就是搭建一个Qt的编程框架,方便后面的学习。这一节会涉及到一些OpenGL的基础方法,多用手册和搜索引擎去理解。

二、   框架结构

    项目的结构如下图。

Qt上的OpenGL 编程(2)动手搭建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();
}

三、程序说明

Qt上的OpenGL 编程(2)动手搭建Qt上的OpenGL编程框架

    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.****.net/vagrxie/article/category/628716/3

1楼wjw_scence3小时前
期待后面有更多教程。。。