1
/****************************************************************************
3
** Copyright (C) 2005-2005 Trolltech AS. All rights reserved.
5
** This file is part of the example classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
36
GLWidget::GLWidget(QWidget *parent)
47
QTimer *timer = new QTimer(this);
48
connect(timer, SIGNAL(timeout()), this, SLOT(advanceGears()));
55
glDeleteLists(gear1, 1);
56
glDeleteLists(gear2, 1);
57
glDeleteLists(gear3, 1);
60
void GLWidget::setXRotation(int angle)
62
normalizeAngle(&angle);
65
emit xRotationChanged(angle);
70
void GLWidget::setYRotation(int angle)
72
normalizeAngle(&angle);
75
emit yRotationChanged(angle);
80
void GLWidget::setZRotation(int angle)
82
normalizeAngle(&angle);
85
emit zRotationChanged(angle);
90
void GLWidget::initializeGL()
92
static const GLfloat lightPos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
93
static const GLfloat reflectance1[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
94
static const GLfloat reflectance2[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
95
static const GLfloat reflectance3[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
97
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
98
glEnable(GL_LIGHTING);
100
glEnable(GL_DEPTH_TEST);
102
gear1 = makeGear(reflectance1, 1.0, 4.0, 1.0, 0.7, 20);
103
gear2 = makeGear(reflectance2, 0.5, 2.0, 2.0, 0.7, 10);
104
gear3 = makeGear(reflectance3, 1.3, 2.0, 0.5, 0.7, 10);
106
glEnable(GL_NORMALIZE);
109
void GLWidget::paintGL()
111
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
114
glRotated(xRot / 16.0, 1.0, 0.0, 0.0);
115
glRotated(yRot / 16.0, 0.0, 1.0, 0.0);
116
glRotated(zRot / 16.0, 0.0, 0.0, 1.0);
118
drawGear(gear1, -3.0, -2.0, 0.0, gear1Rot / 16.0);
119
drawGear(gear2, +3.1, -2.0, 0.0, -2.0 * (gear1Rot / 16.0) - 9.0);
121
glRotated(+90.0, 1.0, 0.0, 0.0);
122
drawGear(gear3, -3.1, -1.8, -2.2, +2.0 * (gear1Rot / 16.0) - 2.0);
127
void GLWidget::resizeGL(int width, int height)
129
int side = qMin(width, height);
130
glViewport((width - side) / 2, (height - side) / 2, side, side);
132
glMatrixMode(GL_PROJECTION);
134
glFrustum(-1.0, +1.0, -1.0, 1.0, 5.0, 60.0);
135
glMatrixMode(GL_MODELVIEW);
137
glTranslated(0.0, 0.0, -40.0);
140
void GLWidget::mousePressEvent(QMouseEvent *event)
142
lastPos = event->pos();
145
void GLWidget::mouseMoveEvent(QMouseEvent *event)
147
int dx = event->x() - lastPos.x();
148
int dy = event->y() - lastPos.y();
150
if (event->buttons() & Qt::LeftButton) {
151
setXRotation(xRot + 8 * dy);
152
setYRotation(yRot + 8 * dx);
153
} else if (event->buttons() & Qt::RightButton) {
154
setXRotation(xRot + 8 * dy);
155
setZRotation(zRot + 8 * dx);
157
lastPos = event->pos();
160
void GLWidget::advanceGears()
166
GLuint GLWidget::makeGear(const GLfloat *reflectance, GLdouble innerRadius,
167
GLdouble outerRadius, GLdouble thickness,
168
GLdouble toothSize, GLint toothCount)
170
const double Pi = 3.14159265358979323846;
172
GLuint list = glGenLists(1);
173
glNewList(list, GL_COMPILE);
174
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, reflectance);
176
GLdouble r0 = innerRadius;
177
GLdouble r1 = outerRadius - toothSize / 2.0;
178
GLdouble r2 = outerRadius + toothSize / 2.0;
179
GLdouble delta = (2.0 * Pi / toothCount) / 4.0;
180
GLdouble z = thickness / 2.0;
183
glShadeModel(GL_FLAT);
185
for (i = 0; i < 2; ++i) {
186
GLdouble sign = (i == 0) ? +1.0 : -1.0;
188
glNormal3d(0.0, 0.0, sign);
190
glBegin(GL_QUAD_STRIP);
191
for (j = 0; j <= toothCount; ++j) {
192
GLdouble angle = 2.0 * Pi * j / toothCount;
193
glVertex3d(r0 * cos(angle), r0 * sin(angle), sign * z);
194
glVertex3d(r1 * cos(angle), r1 * sin(angle), sign * z);
195
glVertex3d(r0 * cos(angle), r0 * sin(angle), sign * z);
196
glVertex3d(r1 * cos(angle + 3 * delta), r1 * sin(angle + 3 * delta),
202
for (j = 0; j < toothCount; ++j) {
203
GLdouble angle = 2.0 * Pi * j / toothCount;
204
glVertex3d(r1 * cos(angle), r1 * sin(angle), sign * z);
205
glVertex3d(r2 * cos(angle + delta), r2 * sin(angle + delta),
207
glVertex3d(r2 * cos(angle + 2 * delta), r2 * sin(angle + 2 * delta),
209
glVertex3d(r1 * cos(angle + 3 * delta), r1 * sin(angle + 3 * delta),
215
glBegin(GL_QUAD_STRIP);
216
for (i = 0; i < toothCount; ++i) {
217
for (j = 0; j < 2; ++j) {
218
GLdouble angle = 2.0 * Pi * (i + (j / 2.0)) / toothCount;
224
glNormal3d(cos(angle), sin(angle), 0.0);
225
glVertex3d(s1 * cos(angle), s1 * sin(angle), +z);
226
glVertex3d(s1 * cos(angle), s1 * sin(angle), -z);
228
glNormal3d(s2 * sin(angle + delta) - s1 * sin(angle),
229
s1 * cos(angle) - s2 * cos(angle + delta), 0.0);
230
glVertex3d(s2 * cos(angle + delta), s2 * sin(angle + delta), +z);
231
glVertex3d(s2 * cos(angle + delta), s2 * sin(angle + delta), -z);
234
glVertex3d(r1, 0.0, +z);
235
glVertex3d(r1, 0.0, -z);
238
glShadeModel(GL_SMOOTH);
240
glBegin(GL_QUAD_STRIP);
241
for (i = 0; i <= toothCount; ++i) {
242
GLdouble angle = i * 2.0 * Pi / toothCount;
243
glNormal3d(-cos(angle), -sin(angle), 0.0);
244
glVertex3d(r0 * cos(angle), r0 * sin(angle), +z);
245
glVertex3d(r0 * cos(angle), r0 * sin(angle), -z);
254
void GLWidget::drawGear(GLuint gear, GLdouble dx, GLdouble dy, GLdouble dz,
258
glTranslated(dx, dy, dz);
259
glRotated(angle, 0.0, 0.0, 1.0);
264
void GLWidget::normalizeAngle(int *angle)
268
while (*angle > 360 * 16)