zoukankan      html  css  js  c++  java
  • OpenGL学习笔记5——嵌入Qt框架

      学习OpenGL也有段时间了,前几篇将GL最基本的画图过程解析了一下,后面进阶的就随项目需要再学。因为之前一直是用glut这个实用工具包来开发很方便,但是会附带一个控制台的窗口,实在觉得有些low,因此就打算将GL嵌入到应用程序中去。

      下面就把前几章学习的知识结合起来,在QT下实现GL的动画。之所以选QT而非MFC原因有2点,一则是QT是开源的,现在开源的东西都很热闹,所以我也凑凑热闹,之前用MFC做过别的上位机程序,我是个喜欢图新鲜的人;二则QT的移植性好,一次编译到处运行吧。

      总结几处注意点:

      1.glut的函数是一个也不能使用了,需要自己用QT的Widget类来创建应用窗口,同时再用QGLWidget类创建自己的GL类,将二者绑定在一起;

      2.需要重载QGLWidget的三个重要函数initializeGL、resizeGL和paintGL;

      3.glClear函数不属于initializeGL,即即使你写入它,在初始化的时候也不会被执行;

      4.需要显示裁剪视口以及设定透视方法,这些在之前使用glut中函数的时候会被默认设置和创建窗口匹配。什么意思呢?就是如果不显示设定的话,你会被坐标定位搞得糊里糊涂。这个也是我第一次移植时候遇到的困扰,其实程序是正常运行的,但是要嘛图像歪斜要嘛看不到图像。如果以上一些设置成功,就能随心所欲绘制;

      5.glut中的消息响应在QT中都有各自的类;

      6.QT的类不比MFC类来的“苗条”,用到哪个查找哪个就ok。

      最后上代码。

    功能说明文件:

    1 --use keyboard to control the cube
    2 -w-    accelerate the rolling speed;
    3 -s-    slow down the rolling speed;
    4 -a-    change the rolling direction;
    5 -d-    opposite with -a-;
    6 -r-    reset the initial state;
    7 -c-    change color

    主函数文件:

    1 #include<QApplication>
    2 #include"myglwidget.h"
    3 int main(int argc,char *argv[])
    4 {
    5     QApplication MyApp(argc,argv);
    6     MyGLWidget MyGL;
    7     MyGL.show();
    8     return MyApp.exec();
    9 }

    自定义GL类头文件:

     1 #ifndef MYGLWIDGET_H
     2 #define MYGLWIDGET_H
     3 
     4 #include <QGLWidget>
     5 #include<QTime>
     6 #include<QTimerEvent>
     7 #include<QKeyEvent>
     8 class MyGLWidget : public QGLWidget
     9 {
    10     Q_OBJECT
    11 public:
    12     explicit MyGLWidget(QWidget *parent = 0);
    13 
    14 signals:
    15 private:
    16 //    GLfloat VertexData[24];
    17 //    GLubyte VertexIndex[6][4];
    18     float m_rotate;
    19     float m_speed;
    20     bool m_angle;
    21     GLubyte m_color_mode;
    22     int m_T20msID;
    23     void initializeGL();
    24     void resizeGL(int w, int h);
    25     void paintGL();
    26     void timerEvent(QTimerEvent *);
    27     void keyPressEvent(QKeyEvent *);
    28     void Cross(GLfloat,GLubyte);
    29     void ChangeColor(GLubyte mode,GLfloat value);
    30     float GetRand(int,int);
    31     void Draw(void);
    32     void Cube(void);
    33 public slots:
    34 };
    35 
    36 #endif // MYGLWIDGET_H

    自定义GL类实现:

      1 #include "myglwidget.h"
      2 static GLfloat VertexData[] = {
      3     -0.5f, -0.5f, -0.5f,
      4      0.5f, -0.5f, -0.5f,
      5     -0.5f,  0.5f, -0.5f,
      6      0.5f,  0.5f, -0.5f,
      7     -0.5f, -0.5f,  0.5f,
      8      0.5f, -0.5f,  0.5f,
      9     -0.5f,  0.5f,  0.5f,
     10      0.5f,  0.5f,  0.5f,
     11 };
     12 static GLubyte VertexIndex[][4] = {
     13     0, 2, 3, 1,
     14     0, 4, 6, 2,
     15     0, 1, 5, 4,
     16     4, 5, 7, 6,
     17     1, 3, 7, 5,
     18     2, 6, 7, 3,
     19 };
     20 MyGLWidget::MyGLWidget(QWidget *parent) :
     21     QGLWidget(parent)
     22 {
     23     m_speed = 2.0;
     24     m_angle = 0;
     25     m_color_mode = 0;
     26     m_rotate = 0;
     27     m_T20msID = 0;
     28 }
     29 void MyGLWidget::initializeGL()
     30 {
     31     glClearColor(0,0,0,0);
     32     glClearDepth(1);
     33     glEnable(GL_DEPTH_TEST);
     34     glDepthFunc(GL_LEQUAL);
     35     m_T20msID = startTimer(20);
     36     qsrand(QTime::currentTime().msec());
     37 }
     38 void MyGLWidget::resizeGL(int w, int h)
     39 {
     40    glViewport(0,0,w,h);
     41    glMatrixMode(GL_PROJECTION);
     42    glLoadIdentity();
     43    if(w <= h)
     44        glOrtho(-1, 1, -(GLfloat)h/(GLfloat)w, (GLfloat)h/(GLfloat)w, -1, 1);
     45    else
     46        glOrtho(-(GLfloat)w/(GLfloat)h, (GLfloat)w/(GLfloat)h, -1, 1, -1, 1);
     47 }
     48 void MyGLWidget::paintGL()
     49 {
     50     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     51     glMatrixMode(GL_MODELVIEW);
     52     glLoadIdentity();
     53     Draw();
     54 }
     55 void MyGLWidget::Cube(void)
     56 {
     57     //enable vertex_array
     58     glEnableClientState(GL_VERTEX_ARRAY);
     59     //load vertex_array data
     60     glVertexPointer(3,GL_FLOAT,3*sizeof(GLfloat),VertexData);
     61     //drawing operation
     62     glDrawElements(GL_QUADS,sizeof(VertexData),GL_UNSIGNED_BYTE,VertexIndex);
     63 }
     64 void MyGLWidget::timerEvent(QTimerEvent *event)
     65 {
     66     if(m_T20msID == event->timerId())
     67     {
     68         updateGL();
     69     }
     70 }
     71 float MyGLWidget::GetRand(int start, int end)
     72 {
     73     return start + (end - start)*qrand()/(RAND_MAX + 1.0);
     74 }
     75 void MyGLWidget::Cross(GLfloat coordinater,GLubyte face)
     76 {
     77         GLfloat rand;
     78         switch(face)
     79         {
     80                 //front
     81                 case 0:    rand = (GetRand(0,10)-5)/10;
     82                                         glBegin(GL_LINES);
     83                                                 glVertex3f(-0.5f,rand,coordinater);
     84                                                 glVertex3f(0.5f,rand,coordinater);
     85                                         glEnd();
     86                                         rand = (GetRand(0,10)-5)/10;
     87                                         glBegin(GL_LINES);
     88                                                 glVertex3f(rand,0.5f,coordinater);
     89                                                 glVertex3f(rand,-0.5f,coordinater);
     90                                         glEnd();
     91                                         break;
     92                 //left
     93                 case 1:    rand = (GetRand(0,10)-5)/10;
     94                                         glBegin(GL_LINES);
     95                                                 glVertex3f(coordinater,-0.5f,rand);
     96                                                 glVertex3f(coordinater,0.5f,rand);
     97                                         glEnd();
     98                                         rand = (GetRand(0,10)-5)/10;
     99                                         glBegin(GL_LINES);
    100                                                 glVertex3f(coordinater,rand,0.5f);
    101                                                 glVertex3f(coordinater,rand,-0.5f);
    102                                         glEnd();
    103                                         break;
    104                 case 2:    rand = (GetRand(0,10)-5)/10;
    105                                         glBegin(GL_LINES);
    106                                                 glVertex3f(-0.5f,coordinater,rand);
    107                                                 glVertex3f(0.5f,coordinater,rand);
    108                                         glEnd();
    109                                         rand = (GetRand(0,10)-5)/10;
    110                                         glBegin(GL_LINES);
    111                                                 glVertex3f(rand,coordinater,0.5f);
    112                                                 glVertex3f(rand,coordinater,-0.5f);
    113                                         glEnd();
    114                                         break;
    115                 default:break;
    116         }
    117 }
    118 void MyGLWidget::Draw()
    119 {
    120     m_rotate += (m_angle)?m_speed:-m_speed;
    121     glRotatef(m_rotate,1,0,0);
    122     glRotatef(m_rotate,0,1,0);
    123     glRotatef(m_rotate,0,0,1);
    124     glColor3f(0,0,0);
    125     //front-red
    126     Cube();
    127     int i;
    128     for(i=0;i<50;i++)
    129     {
    130             //glColor3f(0,GetRand(0,33)/100,0);
    131             ChangeColor(m_color_mode,GetRand(0,20)/100);
    132             glLineWidth(GetRand(1,10));
    133             Cross(0.5f,0);
    134     }
    135     //back-green
    136     for(i=0;i<50;i++)
    137     {
    138             //glColor3f(0,GetRand(0,20)/100,0);
    139             ChangeColor(m_color_mode,GetRand(0,20)/100);
    140             glLineWidth(GetRand(1,10));
    141             Cross(-0.5f,0);
    142     }
    143     //left-blue
    144     for(i=0;i<50;i++)
    145     {
    146             //glColor3f(0,GetRand(46,66)/100,0);
    147             ChangeColor(m_color_mode,GetRand(46,66)/100);
    148             glLineWidth(GetRand(1,10));
    149             Cross(-0.5f,1);
    150     }
    151     //right
    152     for(i=0;i<50;i++)
    153     {
    154             //glColor3f(0,GetRand(33,66)/100,0);
    155             ChangeColor(m_color_mode,GetRand(46,66)/100);
    156             glLineWidth(GetRand(1,10));
    157             Cross(0.5f,1);
    158     }
    159     //up
    160     for(i=0;i<50;i++)
    161     {
    162             //glColor3f(0,GetRand(80,100)/100,0);
    163             ChangeColor(m_color_mode,GetRand(80,100)/100);
    164             glLineWidth(GetRand(1,10));
    165             Cross(0.5f,2);
    166     }
    167     //bottom
    168     for(i=0;i<50;i++)
    169     {
    170             //glColor3f(0,GetRand(66,100)/100,0);
    171             ChangeColor(m_color_mode,GetRand(80,100)/100);
    172             glLineWidth(GetRand(1,10));
    173             Cross(-0.5f,2);
    174     }
    175 
    176 }
    177 void MyGLWidget::ChangeColor(GLubyte mode,GLfloat value)
    178 {
    179         switch(mode)
    180         {
    181                 case 0:glColor3f(0,value,0);
    182                                         break;
    183                 case 1:glColor3f(value,0,0);
    184                                         break;
    185                 case 2:glColor3f(0,0,value);
    186                                         break;
    187                 case 3:glColor3f(value,value,0);
    188                                         break;
    189                 case 4:glColor3f(value,0,value);
    190                                         break;
    191                 case 5:glColor3f(0,value,value);
    192                                         break;
    193                 case 6:glColor3f(value,value,value);
    194                 default:break;
    195         }
    196 }
    197 void MyGLWidget::keyPressEvent(QKeyEvent *event)
    198 {
    199     switch(event->key())
    200     {
    201     case Qt::Key_A:m_angle = 1;
    202         break;
    203     case Qt::Key_W:m_speed += 0.5;
    204         break;
    205     case Qt::Key_D:m_angle = 0;
    206         break;
    207     case Qt::Key_S:if((m_speed-0.25)<0)
    208                         m_speed = 0;
    209                     else
    210                         m_speed -= 0.25;
    211         break;
    212     case Qt::Key_R:m_speed = 2;
    213                    m_angle = 1;
    214                    break;
    215     case Qt::Key_C:if(m_color_mode == 6)
    216                         m_color_mode = 0;
    217                     else
    218                         m_color_mode++;
    219                     break;
    220     case Qt::Key_F:showFullScreen();
    221                     break;
    222     case Qt::Key_Escape:close();
    223     default:break;
    224     }
    225 }
  • 相关阅读:
    PostgreSQL 遇到 column "value" does not exist
    FlowPortal BPM官网改版了,推出20个流程免费基础版
    C#代码规范化(代码风格化)的几个函数
    批量更新带有命名空间的XML文件的多个节点值
    旺财C# .NET代码生成器之DTcms4/5代码批量生成功能
    C# Webform中读取Windows AD/LDAP域用户清单
    在吉日嘎拉DotNet.WebForm中使用FluentScheduler调度任务
    修复一个吉日嘎拉MSSQL数据库版中的分页存储过程bug
    基于吉日嘎拉的OA协同办公模块重写
    基于吉日嘎拉的通用权限管理WebForm版扩展:字典选项管理和缓存管理
  • 原文地址:https://www.cnblogs.com/loadomain/p/3471582.html
Copyright © 2011-2022 走看看