一、
在前面的一篇文章我们已经配置好了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》,
3. 《win32 OpenGL编程 》 一个大牛的博客
https://blog.51cto.com/8672742/1368432