~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to examples/opengl/grabber/glwidget.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2005-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the example classes of the Qt Toolkit.
 
6
**
 
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.
 
10
**
 
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.
 
15
**
 
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.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
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.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include <QtGui>
 
30
#include <QtOpenGL>
 
31
 
 
32
#include <math.h>
 
33
 
 
34
#include "glwidget.h"
 
35
 
 
36
GLWidget::GLWidget(QWidget *parent)
 
37
    : QGLWidget(parent)
 
38
{
 
39
    gear1 = 0;
 
40
    gear2 = 0;
 
41
    gear3 = 0;
 
42
    xRot = 0;
 
43
    yRot = 0;
 
44
    zRot = 0;
 
45
    gear1Rot = 0;
 
46
 
 
47
    QTimer *timer = new QTimer(this);
 
48
    connect(timer, SIGNAL(timeout()), this, SLOT(advanceGears()));
 
49
    timer->start(20);
 
50
}
 
51
 
 
52
GLWidget::~GLWidget()
 
53
{
 
54
    makeCurrent();
 
55
    glDeleteLists(gear1, 1);
 
56
    glDeleteLists(gear2, 1);
 
57
    glDeleteLists(gear3, 1);
 
58
}
 
59
 
 
60
void GLWidget::setXRotation(int angle)
 
61
{
 
62
    normalizeAngle(&angle);
 
63
    if (angle != xRot) {
 
64
        xRot = angle;
 
65
        emit xRotationChanged(angle);
 
66
        updateGL();
 
67
    }
 
68
}
 
69
 
 
70
void GLWidget::setYRotation(int angle)
 
71
{
 
72
    normalizeAngle(&angle);
 
73
    if (angle != yRot) {
 
74
        yRot = angle;
 
75
        emit yRotationChanged(angle);
 
76
        updateGL();
 
77
    }
 
78
}
 
79
 
 
80
void GLWidget::setZRotation(int angle)
 
81
{
 
82
    normalizeAngle(&angle);
 
83
    if (angle != zRot) {
 
84
        zRot = angle;
 
85
        emit zRotationChanged(angle);
 
86
        updateGL();
 
87
    }
 
88
}
 
89
 
 
90
void GLWidget::initializeGL()
 
91
{
 
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 };
 
96
 
 
97
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
 
98
    glEnable(GL_LIGHTING);
 
99
    glEnable(GL_LIGHT0);
 
100
    glEnable(GL_DEPTH_TEST);
 
101
 
 
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);
 
105
 
 
106
    glEnable(GL_NORMALIZE);
 
107
}
 
108
 
 
109
void GLWidget::paintGL()
 
110
{
 
111
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
112
 
 
113
    glPushMatrix();
 
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);
 
117
 
 
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);
 
120
 
 
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);
 
123
 
 
124
    glPopMatrix();
 
125
}
 
126
 
 
127
void GLWidget::resizeGL(int width, int height)
 
128
{
 
129
    int side = qMin(width, height);
 
130
    glViewport((width - side) / 2, (height - side) / 2, side, side);
 
131
 
 
132
    glMatrixMode(GL_PROJECTION);
 
133
    glLoadIdentity();
 
134
    glFrustum(-1.0, +1.0, -1.0, 1.0, 5.0, 60.0);
 
135
    glMatrixMode(GL_MODELVIEW);
 
136
    glLoadIdentity();
 
137
    glTranslated(0.0, 0.0, -40.0);
 
138
}
 
139
 
 
140
void GLWidget::mousePressEvent(QMouseEvent *event)
 
141
{
 
142
    lastPos = event->pos();
 
143
}
 
144
 
 
145
void GLWidget::mouseMoveEvent(QMouseEvent *event)
 
146
{
 
147
    int dx = event->x() - lastPos.x();
 
148
    int dy = event->y() - lastPos.y();
 
149
 
 
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);
 
156
    }
 
157
    lastPos = event->pos();
 
158
}
 
159
 
 
160
void GLWidget::advanceGears()
 
161
{
 
162
    gear1Rot += 2 * 16;
 
163
    updateGL();
 
164
}
 
165
 
 
166
GLuint GLWidget::makeGear(const GLfloat *reflectance, GLdouble innerRadius,
 
167
                          GLdouble outerRadius, GLdouble thickness,
 
168
                          GLdouble toothSize, GLint toothCount)
 
169
{
 
170
    const double Pi = 3.14159265358979323846;
 
171
 
 
172
    GLuint list = glGenLists(1);
 
173
    glNewList(list, GL_COMPILE);
 
174
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, reflectance);
 
175
 
 
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;
 
181
    int i, j;
 
182
 
 
183
    glShadeModel(GL_FLAT);
 
184
 
 
185
    for (i = 0; i < 2; ++i) {
 
186
        GLdouble sign = (i == 0) ? +1.0 : -1.0;
 
187
 
 
188
        glNormal3d(0.0, 0.0, sign);
 
189
 
 
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),
 
197
                       sign * z);
 
198
        }
 
199
        glEnd();
 
200
 
 
201
        glBegin(GL_QUADS);
 
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),
 
206
                       sign * z);
 
207
            glVertex3d(r2 * cos(angle + 2 * delta), r2 * sin(angle + 2 * delta),
 
208
                       sign * z);
 
209
            glVertex3d(r1 * cos(angle + 3 * delta), r1 * sin(angle + 3 * delta),
 
210
                       sign * z);
 
211
        }
 
212
        glEnd();
 
213
    }
 
214
 
 
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;
 
219
            GLdouble s1 = r1;
 
220
            GLdouble s2 = r2;
 
221
            if (j == 1)
 
222
                qSwap(s1, s2);
 
223
 
 
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);
 
227
 
 
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);
 
232
        }
 
233
    }
 
234
    glVertex3d(r1, 0.0, +z);
 
235
    glVertex3d(r1, 0.0, -z);
 
236
    glEnd();
 
237
 
 
238
    glShadeModel(GL_SMOOTH);
 
239
 
 
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);
 
246
    }
 
247
    glEnd();
 
248
 
 
249
    glEndList();
 
250
 
 
251
    return list;
 
252
}
 
253
 
 
254
void GLWidget::drawGear(GLuint gear, GLdouble dx, GLdouble dy, GLdouble dz,
 
255
                        GLdouble angle)
 
256
{
 
257
    glPushMatrix();
 
258
    glTranslated(dx, dy, dz);
 
259
    glRotated(angle, 0.0, 0.0, 1.0);
 
260
    glCallList(gear);
 
261
    glPopMatrix();
 
262
}
 
263
 
 
264
void GLWidget::normalizeAngle(int *angle)
 
265
{
 
266
    while (*angle < 0)
 
267
        *angle += 360 * 16;
 
268
    while (*angle > 360 * 16)
 
269
        *angle -= 360 * 16;
 
270
}