loadomain

博客园 首页 新随笔 联系 订阅 管理

  学习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 }

 

 

posted on 2013-12-12 17:06  loadomain  阅读(1021)  评论(0编辑  收藏  举报