Qt Creator中的3D绘图及动画教程(参照NeHe)
刚刚学习了Qt Creator,发现Qt提供了QtOpenGL模块,对OpenGL做了不错的封装,这使得我们可以很轻松地在Qt程序中使用OpenGL进行绘图渲染。虽然里面还是由不少专业的解释照搬原文的,但还是加入了大量自己的分析。而且Qt中写OpenGL框架上比VC简单太多了,有不少东西都封装优化好了,代码上还是由有很多区别的。当然,其中原教程没解释好的问题我都作了深入的解释,以及一些多余部分解释、代码都被我删掉简化了。
这份Qt OpenGL的3D绘图及动画教程,我基本会按照Nehe的OpenGL教程,只是将代码的实现运用到Qt Creator中,当然其中加了。
下面对Qt中OpenGL做一个简要介绍:
Qt中OpenGL主要是在QGLWidget类中完成的,而要使用QtOpenGL模块,需要在项目文件( .pro)中添加代码"QT+=opengl"。
QGLWidget类是一个用来渲染OpenGL图形的部件,提供了在Qt中显示OpenGL图形的功能。这个类使用起来很简单,只需要继承该类,然后像使用其他QWidget部件一样来使用它。QGLWidget提供了3个方便的纯虚函数,可以在子类中通过重新实现它们来执行典型的OpenGL任务:
initializeGL():设置OpenGL渲染环境,定义显示列表等。该函数只在第一次调用resizeGL()或paintGL()前被自动调用一次。
resizeGL():设置OpenGL的视口、投影等。每次部件改变大小时都会自动调用该函数。
paintGL():渲染OpenGL场景。每当部件需要更新时都会调用该函数。
(以上3个虚函数更具体的调用情况我会用另一篇文章来讲明)
也就是说,Qt中当创建并显示出一个QGLWidget子对象时,会自动依次调用initializeGL()、resizeGL()、paintGL(),完成当前场景的绘制;而当某些情况发生时,会根据情况决定是否自动调用initializeGL()、resizeGL(),一旦调用initializeGL()、resizeGL()了,会紧跟着调用paintGL()对场景进行重新绘制。

实例//*********

在之前说道过VS2010中配合OpenGL绘图的问题,这回是想要说说在QT中使用OpenGL,其实两者并无太大区别,因为都是基于C++语言的。

主要是想简要介绍下OpenGL在QT中的使用方法跟一些错误。

glwidget.h  //继承自QGLWidget,用来实现OpenGL相关的操作以及绘图操作
#ifndef GLWIDGET_H 
 #define GLWIDGET_H 
  
 #include <QtOpenGL> 
 #include <QWidget> 
  
 namespace Ui { 
 class GLWidget; 
 } 
  
 class GLWidget : public QGLWidget 
 { 
     Q_OBJECT 
  
 public: 
     explicit GLWidget(QGLWidget *parent = 0); 
     ~GLWidget(); 
  
 protected: 
     void initializeGL();  //初始化OpenGL窗口部件 
     void paintGL();  //绘制整个OpenGL窗口,只要有更新发生,这个函数就会被调用 
     void resizeGL(int width, int height); //处理窗口大小变化事件的,参数是新状态下的宽和高 
     void keyPressEvent(QKeyEvent *e);  //鼠标处理函数 
  
 protected: 
     bool fullscreen;  //判断是否全屏的变量 
  
 private: 
     Ui::GLWidget *ui; 
 }; 
  
 #endif // GLWIDGET_H   glwidget.cpp  //glwidget.h的源文件
#include "glwidget.h" 
 #include "ui_glwidget.h" 
  
 #include <QtGui> 
 #include <QtCore> 
 #include <QtOpenGL> 
  
 GLWidget::GLWidget(QGLWidget *parent) : 
     QGLWidget(parent), 
     ui(new Ui::GLWidget) 
 { 
     ui->setupUi(this); 
     fullscreen = false; 
 } 
  
 //这是对虚函数,这里是重写该函数 
 void GLWidget::initializeGL() 
 { 
     setGeometry(300, 200, 640, 480);//设置窗口初始位置和大小 
     glShadeModel(GL_FLAT);//设置阴影平滑模式 
     glClearColor(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 GLWidget::paintGL() 
 { 
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
     glLoadIdentity(); 
  
         //renderText(10,20,"Hello,My Dear"); 
   // glColor3f(1.0, 0.0, 0.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();
     */ 
     glBegin(GL_TRIANGLES); 
         glColor3f(1.0f, 0.0f, 0.0f); 
             glVertex3f(0.0f, 1.0f, 0.0f); 
         glColor3f(0.0f, 1.0f, 0.0f); 
             glVertex3f(-1.0f, -1.0f, 0.0f); 
         glColor3f(0.0f, 0.0f, 1.0f); 
             glVertex3f(1.0f, -1.0f, 0.0f); 
     glEnd(); 
     renderText(20, 100, "Hello Jcy, My first OpenGL app."); 
 } 
  
 //该程序是设置opengl场景透视图,程序中至少被执行一次(程序启动时). 
 void GLWidget::resizeGL(int width, int height) 
 { 
     if(0 == height) 
         height = 1;//防止一条边为0 
     glViewport(0, 0, (GLint)width, (GLint)height);//重置当前视口,本身不是重置窗口的,只不过是这里被Qt给封装好了 
     glMatrixMode(GL_PROJECTION);//选择投影矩阵 
     glLoadIdentity();//重置选择好的投影矩阵 
   // gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0);//建立透视投影矩阵 
   //  glMatirxMode(GL_MODELVIEW);//以下2句和上面出现的解释一样 
     glLoadIdentity(); 
 } 
  
 void GLWidget::keyPressEvent(QKeyEvent *e) 
 { 
     switch(e->key()) 
     { 
         //F1键为全屏和普通屏显示切换键 
         case Qt::Key_F1: 
             fullscreen = !fullscreen; 
             if(fullscreen) 
                 showFullScreen(); 
             else 
             { 
                 setGeometry(300, 150, 640, 480); 
                 showNormal(); 
             } 
             updateGL(); 
             break; 
         //Ese为退出程序键 
         case Qt::Key_Escape: 
             close(); 
     } 
 } 
  
 GLWidget::~GLWidget() 
 { 
     delete ui; 
 } main.cpp //原始cpp文件,未改变
#include <QtGui/QApplication> 
 #include "glwidget.h" 
  
 int main(int argc, char *argv[]) 
 { 
     QApplication a(argc, argv); 
     GLWidget w; 
     w.show(); 
      
     return a.exec(); 
 }

QT 图表demo qt 图表 opengl_#include

说明:
(1) 绘图工作:

voidGLWidget::paintGL()

这个是主要的绘图函数,整个的绘图工作都在这个里面。

(2) 坐标点:

OpenGL的坐标点的范围-1到1。

(3) 如何在OpenGL图形周围写字:

renderText(20,100,"HelloJcy,MyfirstOpenGLapp.");

第一个跟第二个参数是坐标位置,第三个是需要显示的字。

可能出现的错误:

(1)错误:C1083: Cannot open include file: 'QtOpenGL': No such file or directory

如果你是这个错误,那么你需要在.pro文件中添加QT += opengl

(2)错误:C2504: 'QGLWidget' : base class undefined

如果你是这个错误,那么请你在.h文件中添加 #include<QtOpenGL>

(3)错误:C2039: 'show' : is not a member of 'GLWidget'

如果你是这个错误,那么请你在.h文件中添加 #include<QtOpenGL>