~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kwin/effects/_test/gears.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************
 
2
KWin - the KDE window manager
 
3
This file is part of the KDE project.
 
4
 
 
5
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
 
6
 
 
7
This program is free software; you can redistribute it and/or modify
 
8
it under the terms of the GNU General Public License as published by
 
9
the Free Software Foundation; either version 2 of the License, or
 
10
(at your option) any later version.
 
11
 
 
12
This program is distributed in the hope that it will be useful,
 
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
GNU General Public License for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License
 
18
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
Based on Compiz Fusion cube gear plugin by Dennis Kasprzyk:
 
21
    http://gitweb.compiz-fusion.org/?p=fusion/plugins/gears;a=blob;f=gears.c;hb=HEAD
 
22
Which is based on glxgears.c by Brian Paul:
 
23
    http://cvsweb.xfree86.org/cvsweb/xc/programs/glxgears/glxgears.c
 
24
*********************************************************************/
 
25
 
 
26
#include "gears.h"
 
27
#include "../cube/cube_proxy.h"
 
28
 
 
29
#include <math.h>
 
30
 
 
31
#include <GL/gl.h>
 
32
 
 
33
namespace KWin
 
34
{
 
35
 
 
36
KWIN_EFFECT(gears, GearsEffect)
 
37
KWIN_EFFECT_SUPPORTED(gears, GearsEffect::supported())
 
38
 
 
39
GearsEffect::GearsEffect()
 
40
    : CubeInsideEffect()
 
41
    , m_active(false)
 
42
    , m_contentRotation(0.0f)
 
43
    , m_angle(0.0f)
 
44
{
 
45
    CubeEffectProxy* proxy =
 
46
        static_cast<CubeEffectProxy*>(effects->getProxy("cube"));
 
47
    if (proxy)
 
48
        proxy->registerCubeInsideEffect(this);
 
49
}
 
50
 
 
51
GearsEffect::~GearsEffect()
 
52
{
 
53
    CubeEffectProxy* proxy =
 
54
        static_cast<CubeEffectProxy*>(effects->getProxy("cube"));
 
55
    if (proxy)
 
56
        proxy->unregisterCubeInsideEffect(this);
 
57
}
 
58
 
 
59
bool GearsEffect::supported()
 
60
{
 
61
    return effects->compositingType() == OpenGLCompositing;
 
62
}
 
63
 
 
64
void GearsEffect::prePaintScreen(ScreenPrePaintData& data, int time)
 
65
{
 
66
    if (m_active) {
 
67
        m_contentRotation += time * 360.0f / 20000.0f;
 
68
        if (m_contentRotation > 360.0f)
 
69
            m_contentRotation -= 360.0f;
 
70
        m_angle += time * 360.0f / 8000.0f;
 
71
        if (m_angle > 360.0f)
 
72
            m_angle -= 360.0f;
 
73
    }
 
74
    effects->prePaintScreen(data, time);
 
75
}
 
76
 
 
77
void GearsEffect::postPaintScreen()
 
78
{
 
79
    if (m_active) {
 
80
        effects->addRepaintFull();
 
81
    }
 
82
    effects->postPaintScreen();
 
83
}
 
84
 
 
85
 
 
86
void GearsEffect::paint()
 
87
{
 
88
    if (m_active) {
 
89
        paintGears();
 
90
    }
 
91
}
 
92
 
 
93
void GearsEffect::setActive(bool active)
 
94
{
 
95
    m_active = active;
 
96
    if (active)
 
97
        initGears();
 
98
    else
 
99
        endGears();
 
100
}
 
101
 
 
102
void GearsEffect::gear(float inner_radius, float outer_radius, float width, int teeth, float tooth_depth)
 
103
{
 
104
    GLint i;
 
105
    GLfloat r0, r1, r2, maxr2, minr2;
 
106
    GLfloat angle, da;
 
107
    GLfloat u, v, len;
 
108
 
 
109
    r0 = inner_radius;
 
110
    r1 = outer_radius - tooth_depth / 2.0;
 
111
    maxr2 = r2 = outer_radius + tooth_depth / 2.0;
 
112
    minr2 = r2;
 
113
 
 
114
    da = 2.0 * M_PI / teeth / 4.0;
 
115
 
 
116
    glShadeModel(GL_FLAT);
 
117
 
 
118
    glNormal3f(0.0, 0.0, 1.0);
 
119
 
 
120
    /* draw front face */
 
121
    glBegin(GL_QUAD_STRIP);
 
122
 
 
123
    for (i = 0; i <= teeth; ++i) {
 
124
        angle = i * 2.0 * M_PI / teeth;
 
125
        glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
126
        glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
127
 
 
128
        if (i < teeth) {
 
129
            glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
130
            glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
 
131
        }
 
132
    }
 
133
 
 
134
    glEnd();
 
135
 
 
136
    /* draw front sides of teeth */
 
137
    glBegin(GL_QUADS);
 
138
 
 
139
    for (i = 0; i < teeth; ++i) {
 
140
        angle = i * 2.0 * M_PI / teeth;
 
141
 
 
142
        glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
143
        glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
 
144
        glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
 
145
        glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
 
146
        r2 = minr2;
 
147
    }
 
148
 
 
149
    r2 = maxr2;
 
150
 
 
151
    glEnd();
 
152
 
 
153
    glNormal3f(0.0, 0.0, -1.0);
 
154
 
 
155
    /* draw back face */
 
156
    glBegin(GL_QUAD_STRIP);
 
157
 
 
158
    for (i = 0; i <= teeth; ++i) {
 
159
        angle = i * 2.0 * M_PI / teeth;
 
160
        glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
161
        glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
162
 
 
163
        if (i < teeth) {
 
164
            glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
 
165
            glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
166
        }
 
167
    }
 
168
 
 
169
    glEnd();
 
170
 
 
171
    /* draw back sides of teeth */
 
172
    glBegin(GL_QUADS);
 
173
    da = 2.0 * M_PI / teeth / 4.0;
 
174
 
 
175
    for (i = 0; i < teeth; ++i) {
 
176
        angle = i * 2.0 * M_PI / teeth;
 
177
 
 
178
        glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
 
179
        glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
 
180
        glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
 
181
        glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
182
        r2 = minr2;
 
183
    }
 
184
 
 
185
    r2 = maxr2;
 
186
 
 
187
    glEnd();
 
188
 
 
189
    /* draw outward faces of teeth */
 
190
    glBegin(GL_QUAD_STRIP);
 
191
 
 
192
    for (i = 0; i < teeth; ++i) {
 
193
        angle = i * 2.0 * M_PI / teeth;
 
194
 
 
195
        glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
 
196
        glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
 
197
        u = r2 * cos(angle + da) - r1 * cos(angle);
 
198
        v = r2 * sin(angle + da) - r1 * sin(angle);
 
199
        len = sqrt(u * u + v * v);
 
200
        u /= len;
 
201
        v /= len;
 
202
        glNormal3f(v, -u, 0.0);
 
203
        glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
 
204
        glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
 
205
        glNormal3f(cos(angle + 1.5 * da), sin(angle + 1.5 * da), 0.0);
 
206
        glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
 
207
        glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
 
208
        u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
 
209
        v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
 
210
        glNormal3f(v, -u, 0.0);
 
211
        glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
 
212
        glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
 
213
        glNormal3f(cos(angle + 3.5 * da), sin(angle + 3.5 * da), 0.0);
 
214
        r2 = minr2;
 
215
    }
 
216
 
 
217
    r2 = maxr2;
 
218
 
 
219
    glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
 
220
    glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
 
221
 
 
222
    glEnd();
 
223
 
 
224
    glShadeModel(GL_SMOOTH);
 
225
 
 
226
    /* draw inside radius cylinder */
 
227
    glBegin(GL_QUAD_STRIP);
 
228
 
 
229
    for (i = 0; i <= teeth; ++i) {
 
230
        angle = i * 2.0 * M_PI / teeth;
 
231
        glNormal3f(-cos(angle), -sin(angle), 0.0);
 
232
        glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
 
233
        glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
 
234
    }
 
235
    glEnd();
 
236
}
 
237
 
 
238
void GearsEffect::paintGears()
 
239
{
 
240
    static GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
 
241
    QRect rect = effects->clientArea(FullArea, effects->activeScreen(), effects->currentDesktop());
 
242
 
 
243
    glPushMatrix();
 
244
    // invert scale
 
245
    float fovy = 60.0f;
 
246
    float zNear = 0.1f;
 
247
    float ymax = zNear * tan(fovy  * M_PI / 360.0f);
 
248
    float ymin = -ymax;
 
249
    float xmin =  ymin;
 
250
    float xmax = ymax;
 
251
    float scaleFactor = 1.1 * tan(fovy * M_PI / 360.0f) / ymax;
 
252
    glScalef(1.0f / ((xmax - xmin)*scaleFactor / displayWidth()), 1.0f / (-(ymax - ymin)*scaleFactor / displayHeight()), 1000.0f);
 
253
 
 
254
    glPushAttrib(GL_COLOR_BUFFER_BIT | GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT);
 
255
 
 
256
    glDisable(GL_BLEND);
 
257
 
 
258
    glPushMatrix();
 
259
 
 
260
    // content rotation requires depth test - so disabled
 
261
//     glRotatef( m_contentRotation, 0.0, 1.0, 0.0 );
 
262
 
 
263
    glScalef(0.05, 0.05, 0.05);
 
264
 
 
265
    glEnable(GL_NORMALIZE);
 
266
    glEnable(GL_LIGHTING);
 
267
    glEnable(GL_LIGHT1);
 
268
    glDisable(GL_COLOR_MATERIAL);
 
269
 
 
270
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
271
 
 
272
    glPushMatrix();
 
273
    glTranslatef(-3.0, -2.0, 0.0);
 
274
    glRotatef(m_angle, 0.0, 0.0, 1.0);
 
275
    glCallList(m_gear1);
 
276
    glPopMatrix();
 
277
 
 
278
    glPushMatrix();
 
279
    glTranslatef(3.1, -2.0, 0.0);
 
280
    glRotatef(-2.0 * m_angle - 9.0, 0.0, 0.0, 1.0);
 
281
    glCallList(m_gear2);
 
282
    glPopMatrix();
 
283
 
 
284
    glPushMatrix();
 
285
    glTranslatef(-3.1, 4.2, 0.0);
 
286
    glRotatef(-2.0 * m_angle - 25.0, 0.0, 0.0, 1.0);
 
287
    glCallList(m_gear3);
 
288
    glPopMatrix();
 
289
 
 
290
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, white);
 
291
 
 
292
    glPopMatrix();
 
293
 
 
294
    glDisable(GL_LIGHT1);
 
295
    glDisable(GL_NORMALIZE);
 
296
    glEnable(GL_COLOR_MATERIAL);
 
297
 
 
298
    glDisable(GL_LIGHTING);
 
299
 
 
300
    glPopMatrix();
 
301
    glPopAttrib();
 
302
}
 
303
 
 
304
void GearsEffect::initGears()
 
305
{
 
306
    static GLfloat pos[4]         = { 5.0f, 5.0f, 10.0f, 0.0f };
 
307
    static GLfloat red[4]         = { 0.8f, 0.1f, 0.0f, 1.0f };
 
308
    static GLfloat green[4]       = { 0.0f, 0.8f, 0.2f, 1.0f };
 
309
    static GLfloat blue[4]        = { 0.2f, 0.2f, 1.0f, 1.0f };
 
310
    static GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 0.3f };
 
311
    static GLfloat diffuseLight[] = { 0.5f, 0.5f, 0.5f, 0.5f };
 
312
 
 
313
    glLightfv(GL_LIGHT1, GL_AMBIENT, ambientLight);
 
314
    glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseLight);
 
315
    glLightfv(GL_LIGHT1, GL_POSITION, pos);
 
316
 
 
317
    m_gear1 = glGenLists(1);
 
318
    glNewList(m_gear1, GL_COMPILE);
 
319
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
 
320
    gear(1.0f, 4.0f, 1.0f, 20, 0.7f);
 
321
    glEndList();
 
322
 
 
323
    m_gear2 = glGenLists(1);
 
324
    glNewList(m_gear2, GL_COMPILE);
 
325
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
 
326
    gear(0.5f, 2.0f, 2.0f, 10, 0.7f);
 
327
    glEndList();
 
328
 
 
329
    m_gear3 = glGenLists(1);
 
330
    glNewList(m_gear3, GL_COMPILE);
 
331
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
 
332
    gear(1.3f, 2.0f, 0.5f, 10, 0.7f);
 
333
    glEndList();
 
334
}
 
335
 
 
336
void GearsEffect::endGears()
 
337
{
 
338
    glDeleteLists(m_gear1, 1);
 
339
    glDeleteLists(m_gear2, 1);
 
340
    glDeleteLists(m_gear3, 1);
 
341
}
 
342
 
 
343
} // namespace