source: trunk/examples/opengl/grabber/glwidget.cpp@ 641

Last change on this file since 641 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 8.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtGui>
43#include <QtOpenGL>
44
45#include <math.h>
46
47#include "glwidget.h"
48
49GLWidget::GLWidget(QWidget *parent)
50 : QGLWidget(parent)
51{
52 gear1 = 0;
53 gear2 = 0;
54 gear3 = 0;
55 xRot = 0;
56 yRot = 0;
57 zRot = 0;
58 gear1Rot = 0;
59
60 QTimer *timer = new QTimer(this);
61 connect(timer, SIGNAL(timeout()), this, SLOT(advanceGears()));
62 timer->start(20);
63}
64
65GLWidget::~GLWidget()
66{
67 makeCurrent();
68 glDeleteLists(gear1, 1);
69 glDeleteLists(gear2, 1);
70 glDeleteLists(gear3, 1);
71}
72
73void GLWidget::setXRotation(int angle)
74{
75 normalizeAngle(&angle);
76 if (angle != xRot) {
77 xRot = angle;
78 emit xRotationChanged(angle);
79 updateGL();
80 }
81}
82
83void GLWidget::setYRotation(int angle)
84{
85 normalizeAngle(&angle);
86 if (angle != yRot) {
87 yRot = angle;
88 emit yRotationChanged(angle);
89 updateGL();
90 }
91}
92
93void GLWidget::setZRotation(int angle)
94{
95 normalizeAngle(&angle);
96 if (angle != zRot) {
97 zRot = angle;
98 emit zRotationChanged(angle);
99 updateGL();
100 }
101}
102
103void GLWidget::initializeGL()
104{
105 static const GLfloat lightPos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
106 static const GLfloat reflectance1[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
107 static const GLfloat reflectance2[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
108 static const GLfloat reflectance3[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
109
110 glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
111 glEnable(GL_LIGHTING);
112 glEnable(GL_LIGHT0);
113 glEnable(GL_DEPTH_TEST);
114
115 gear1 = makeGear(reflectance1, 1.0, 4.0, 1.0, 0.7, 20);
116 gear2 = makeGear(reflectance2, 0.5, 2.0, 2.0, 0.7, 10);
117 gear3 = makeGear(reflectance3, 1.3, 2.0, 0.5, 0.7, 10);
118
119 glEnable(GL_NORMALIZE);
120 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
121}
122
123void GLWidget::paintGL()
124{
125 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
126
127 glPushMatrix();
128 glRotated(xRot / 16.0, 1.0, 0.0, 0.0);
129 glRotated(yRot / 16.0, 0.0, 1.0, 0.0);
130 glRotated(zRot / 16.0, 0.0, 0.0, 1.0);
131
132 drawGear(gear1, -3.0, -2.0, 0.0, gear1Rot / 16.0);
133 drawGear(gear2, +3.1, -2.0, 0.0, -2.0 * (gear1Rot / 16.0) - 9.0);
134
135 glRotated(+90.0, 1.0, 0.0, 0.0);
136 drawGear(gear3, -3.1, -1.8, -2.2, +2.0 * (gear1Rot / 16.0) - 2.0);
137
138 glPopMatrix();
139}
140
141void GLWidget::resizeGL(int width, int height)
142{
143 int side = qMin(width, height);
144 glViewport((width - side) / 2, (height - side) / 2, side, side);
145
146 glMatrixMode(GL_PROJECTION);
147 glLoadIdentity();
148 glFrustum(-1.0, +1.0, -1.0, 1.0, 5.0, 60.0);
149 glMatrixMode(GL_MODELVIEW);
150 glLoadIdentity();
151 glTranslated(0.0, 0.0, -40.0);
152}
153
154void GLWidget::mousePressEvent(QMouseEvent *event)
155{
156 lastPos = event->pos();
157}
158
159void GLWidget::mouseMoveEvent(QMouseEvent *event)
160{
161 int dx = event->x() - lastPos.x();
162 int dy = event->y() - lastPos.y();
163
164 if (event->buttons() & Qt::LeftButton) {
165 setXRotation(xRot + 8 * dy);
166 setYRotation(yRot + 8 * dx);
167 } else if (event->buttons() & Qt::RightButton) {
168 setXRotation(xRot + 8 * dy);
169 setZRotation(zRot + 8 * dx);
170 }
171 lastPos = event->pos();
172}
173
174void GLWidget::advanceGears()
175{
176 gear1Rot += 2 * 16;
177 updateGL();
178}
179
180GLuint GLWidget::makeGear(const GLfloat *reflectance, GLdouble innerRadius,
181 GLdouble outerRadius, GLdouble thickness,
182 GLdouble toothSize, GLint toothCount)
183{
184 const double Pi = 3.14159265358979323846;
185
186 GLuint list = glGenLists(1);
187 glNewList(list, GL_COMPILE);
188 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, reflectance);
189
190 GLdouble r0 = innerRadius;
191 GLdouble r1 = outerRadius - toothSize / 2.0;
192 GLdouble r2 = outerRadius + toothSize / 2.0;
193 GLdouble delta = (2.0 * Pi / toothCount) / 4.0;
194 GLdouble z = thickness / 2.0;
195 int i, j;
196
197 glShadeModel(GL_FLAT);
198
199 for (i = 0; i < 2; ++i) {
200 GLdouble sign = (i == 0) ? +1.0 : -1.0;
201
202 glNormal3d(0.0, 0.0, sign);
203
204 glBegin(GL_QUAD_STRIP);
205 for (j = 0; j <= toothCount; ++j) {
206 GLdouble angle = 2.0 * Pi * j / toothCount;
207 glVertex3d(r0 * cos(angle), r0 * sin(angle), sign * z);
208 glVertex3d(r1 * cos(angle), r1 * sin(angle), sign * z);
209 glVertex3d(r0 * cos(angle), r0 * sin(angle), sign * z);
210 glVertex3d(r1 * cos(angle + 3 * delta), r1 * sin(angle + 3 * delta),
211 sign * z);
212 }
213 glEnd();
214
215 glBegin(GL_QUADS);
216 for (j = 0; j < toothCount; ++j) {
217 GLdouble angle = 2.0 * Pi * j / toothCount;
218 glVertex3d(r1 * cos(angle), r1 * sin(angle), sign * z);
219 glVertex3d(r2 * cos(angle + delta), r2 * sin(angle + delta),
220 sign * z);
221 glVertex3d(r2 * cos(angle + 2 * delta), r2 * sin(angle + 2 * delta),
222 sign * z);
223 glVertex3d(r1 * cos(angle + 3 * delta), r1 * sin(angle + 3 * delta),
224 sign * z);
225 }
226 glEnd();
227 }
228
229 glBegin(GL_QUAD_STRIP);
230 for (i = 0; i < toothCount; ++i) {
231 for (j = 0; j < 2; ++j) {
232 GLdouble angle = 2.0 * Pi * (i + (j / 2.0)) / toothCount;
233 GLdouble s1 = r1;
234 GLdouble s2 = r2;
235 if (j == 1)
236 qSwap(s1, s2);
237
238 glNormal3d(cos(angle), sin(angle), 0.0);
239 glVertex3d(s1 * cos(angle), s1 * sin(angle), +z);
240 glVertex3d(s1 * cos(angle), s1 * sin(angle), -z);
241
242 glNormal3d(s2 * sin(angle + delta) - s1 * sin(angle),
243 s1 * cos(angle) - s2 * cos(angle + delta), 0.0);
244 glVertex3d(s2 * cos(angle + delta), s2 * sin(angle + delta), +z);
245 glVertex3d(s2 * cos(angle + delta), s2 * sin(angle + delta), -z);
246 }
247 }
248 glVertex3d(r1, 0.0, +z);
249 glVertex3d(r1, 0.0, -z);
250 glEnd();
251
252 glShadeModel(GL_SMOOTH);
253
254 glBegin(GL_QUAD_STRIP);
255 for (i = 0; i <= toothCount; ++i) {
256 GLdouble angle = i * 2.0 * Pi / toothCount;
257 glNormal3d(-cos(angle), -sin(angle), 0.0);
258 glVertex3d(r0 * cos(angle), r0 * sin(angle), +z);
259 glVertex3d(r0 * cos(angle), r0 * sin(angle), -z);
260 }
261 glEnd();
262
263 glEndList();
264
265 return list;
266}
267
268void GLWidget::drawGear(GLuint gear, GLdouble dx, GLdouble dy, GLdouble dz,
269 GLdouble angle)
270{
271 glPushMatrix();
272 glTranslated(dx, dy, dz);
273 glRotated(angle, 0.0, 0.0, 1.0);
274 glCallList(gear);
275 glPopMatrix();
276}
277
278void GLWidget::normalizeAngle(int *angle)
279{
280 while (*angle < 0)
281 *angle += 360 * 16;
282 while (*angle > 360 * 16)
283 *angle -= 360 * 16;
284}
Note: See TracBrowser for help on using the repository browser.