~smspillaz/compiz-plugins-main/compiz-plugins-main.work_923683

« back to all changes in this revision

Viewing changes to animation/src/grid.cpp

  • Committer: Sam Spilsbury
  • Date: 2011-08-12 06:41:38 UTC
  • Revision ID: sam.spilsbury@canonical.com-20110812064138-sg45sswip9zgk0og
Sync in changes from upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Animation plugin for compiz/beryl
 
3
 *
 
4
 * animation.c
 
5
 *
 
6
 * Copyright : (C) 2006 Erkin Bahceci
 
7
 * E-mail    : erkinbah@gmail.com
 
8
 *
 
9
 * Based on Wobbly and Minimize plugins by
 
10
 *           : David Reveman
 
11
 * E-mail    : davidr@novell.com>
 
12
 *
 
13
 * Particle system added by : (C) 2006 Dennis Kasprzyk
 
14
 * E-mail                   : onestone@beryl-project.org
 
15
 *
 
16
 * Beam-Up added by : Florencio Guimaraes
 
17
 * E-mail           : florencio@nexcorp.com.br
 
18
 *
 
19
 * Hexagon tessellator added by : Mike Slegeir
 
20
 * E-mail                       : mikeslegeir@mail.utexas.edu>
 
21
 *
 
22
 * This program is free software; you can redistribute it and/or
 
23
 * modify it under the terms of the GNU General Public License
 
24
 * as published by the Free Software Foundation; either version 2
 
25
 * of the License, or (at your option) any later version.
 
26
 *
 
27
 * This program is distributed in the hope that it will be useful,
 
28
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
29
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
30
 * GNU General Public License for more details.
 
31
 *
 
32
 * You should have received a copy of the GNU General Public License
 
33
 * along with this program; if not, write to the Free Software
 
34
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
35
 */
 
36
 
 
37
#include "private.h"
 
38
 
 
39
// =====================  Effect: Dodge  =========================
 
40
 
 
41
GridAnim::GridModel::GridObject::GridObject () :
 
42
    mPosition (0, 0, 0),
 
43
    mGridPosition (0, 0),
 
44
    mOffsetTexCoordForQuadBefore (0, 0),
 
45
    mOffsetTexCoordForQuadAfter (0, 0)
 
46
{
 
47
}
 
48
 
 
49
void
 
50
GridAnim::GridModel::GridObject::setGridPosition (Point &gridPosition)
 
51
{
 
52
    mGridPosition = gridPosition;
 
53
}
 
54
 
 
55
GridAnim::GridModel::GridModel (CompWindow *w,
 
56
                                WindowEvent curWindowEvent,
 
57
                                int height,
 
58
                                int gridWidth,
 
59
                                int gridHeight,
 
60
                                int decorTopHeight,
 
61
                                int decorBottomHeight) :
 
62
    mScale (1.0f, 1.0f),
 
63
    mScaleOrigin (0, 0)
 
64
{
 
65
    mNumObjects = (unsigned)(gridWidth * gridHeight);
 
66
    mObjects = new GridObject[mNumObjects];
 
67
 
 
68
    initObjects (curWindowEvent,
 
69
                 height,
 
70
                 gridWidth, gridHeight,
 
71
                 decorTopHeight, decorBottomHeight);
 
72
}
 
73
 
 
74
GridAnim::GridModel::~GridModel ()
 
75
{
 
76
    delete[] mObjects;
 
77
}
 
78
 
 
79
void
 
80
GridAnim::GridModel::initObjects (WindowEvent curWindowEvent,
 
81
                                  int height,
 
82
                                  int gridWidth, int gridHeight,
 
83
                                  int decorTopHeight, int decorBottomHeight)
 
84
{
 
85
    int gridX, gridY;
 
86
    int nGridCellsX, nGridCellsY;
 
87
 
 
88
    // number of grid cells in x direction
 
89
    nGridCellsX = gridWidth - 1;
 
90
 
 
91
    if (curWindowEvent == WindowEventShade ||
 
92
        curWindowEvent == WindowEventUnshade)
 
93
    {
 
94
        // Number of grid cells in y direction.
 
95
        // One allocated for top, one for bottom.
 
96
        nGridCellsY = gridHeight - 3;
 
97
 
 
98
        float winContentsHeight =
 
99
            height - decorTopHeight - decorBottomHeight;
 
100
 
 
101
        //Top
 
102
        for (gridX = 0; gridX < gridWidth; gridX++)
 
103
        {
 
104
            Point gridPos ((float)gridX / nGridCellsX, 0);
 
105
 
 
106
            mObjects[gridX].setGridPosition (gridPos);
 
107
        }
 
108
 
 
109
        // Window contents
 
110
        for (gridY = 1; gridY < gridHeight - 1; gridY++)
 
111
        {
 
112
            float inWinY =
 
113
                (gridY - 1) * winContentsHeight / nGridCellsY +
 
114
                decorTopHeight;
 
115
            float gridPosY = inWinY / height;
 
116
 
 
117
            for (gridX = 0; gridX < gridWidth; gridX++)
 
118
            {
 
119
                Point gridPos ((float)gridX / nGridCellsX, gridPosY);
 
120
                mObjects[gridY * gridWidth + gridX].setGridPosition (gridPos);
 
121
            }
 
122
        }
 
123
 
 
124
        // Bottom (gridY is gridHeight-1 now)
 
125
        for (gridX = 0; gridX < gridWidth; gridX++)
 
126
        {
 
127
            Point gridPos ((float)gridX / nGridCellsX, 1);
 
128
            mObjects[gridY * gridWidth + gridX].setGridPosition (gridPos);
 
129
        }
 
130
    }
 
131
    else
 
132
    {
 
133
        int objIndex = 0;
 
134
 
 
135
        // number of grid cells in y direction
 
136
        nGridCellsY = gridHeight - 1;
 
137
 
 
138
        for (gridY = 0; gridY < gridHeight; gridY++)
 
139
        {
 
140
            for (gridX = 0; gridX < gridWidth; gridX++)
 
141
            {
 
142
                // TODO Optimize
 
143
                Point gridPos ((float)gridX / nGridCellsX,
 
144
                               (float)gridY / nGridCellsY);
 
145
                mObjects[objIndex].setGridPosition (gridPos);
 
146
                objIndex++;
 
147
            }
 
148
        }
 
149
    }
 
150
}
 
151
 
 
152
void
 
153
GridAnim::GridModel::move (float tx,
 
154
                           float ty)
 
155
{
 
156
    GridObject *object = mObjects;
 
157
    for (unsigned int i = 0; i < mNumObjects; i++, object++)
 
158
    {
 
159
        object->mPosition.add (Point3d (tx, ty, 0));
 
160
    }
 
161
}
 
162
 
 
163
void
 
164
GridAnim::updateBB (CompOutput &output)
 
165
{
 
166
    GridModel::GridObject *object = mModel->mObjects;
 
167
    for (unsigned int i = 0; i < mModel->mNumObjects; i++, object++)
 
168
    {
 
169
        mAWindow->expandBBWithPoint (object->position ().x () + 0.5,
 
170
                                     object->position ().y () + 0.5);
 
171
    }
 
172
}
 
173
 
 
174
void
 
175
GridAnim::initGrid ()
 
176
{
 
177
    mGridWidth = 2;
 
178
    mGridHeight = 2;
 
179
}
 
180
 
 
181
GridAnim::GridAnim (CompWindow *w,
 
182
                    WindowEvent curWindowEvent,
 
183
                    float duration,
 
184
                    const AnimEffect info,
 
185
                    const CompRect &icon) :
 
186
    Animation::Animation (w, curWindowEvent, duration, info, icon),
 
187
    mModel (NULL),
 
188
    mUseQTexCoord (false)
 
189
{
 
190
}
 
191
 
 
192
void
 
193
GridAnim::init ()
 
194
{
 
195
    initGrid ();
 
196
 
 
197
    CompRect outRect (mAWindow->savedRectsValid () ?
 
198
                      mAWindow->savedOutRect () :
 
199
                      mWindow->outputRect ());
 
200
 
 
201
    mModel = new GridModel (mWindow, mCurWindowEvent,
 
202
                            outRect.height (),
 
203
                            mGridWidth, mGridHeight,
 
204
                            mDecorTopHeight, mDecorBottomHeight);
 
205
}
 
206
 
 
207
GridAnim::~GridAnim ()
 
208
{
 
209
    if (mModel)
 
210
        delete mModel;
 
211
}
 
212
 
 
213
void
 
214
GridAnim::addGeometry (const GLTexture::MatrixList &matrix,
 
215
                       const CompRegion            &region,
 
216
                       const CompRegion            &clip,
 
217
                       unsigned int                maxGridWidth,
 
218
                       unsigned int                maxGridHeight)
 
219
{
 
220
    unsigned int nMatrix = matrix.size ();
 
221
    int nVertices, nIndices;
 
222
    GLushort *i;
 
223
    GLfloat *v;
 
224
    int x1, y1, x2, y2;
 
225
    float winContentsY, winContentsHeight;
 
226
    float deformedX, deformedY;
 
227
    float deformedZ = 0;
 
228
    int nVertX, nVertY;
 
229
    int vSize;
 
230
    float gridW, gridH;
 
231
    bool rect = true;
 
232
    bool notUsing3dCoords = !using3D ();
 
233
 
 
234
    if (region.isEmpty ()) // nothing to do
 
235
        return;
 
236
 
 
237
    GLWindow::Geometry &geometry = GLWindow::get (mWindow)->geometry ();
 
238
 
 
239
    for (unsigned int it = 0; it < nMatrix; it++)
 
240
    {
 
241
        if (matrix[it].xy != 0.0f || matrix[it].yx != 0.0f)
 
242
        {
 
243
            rect = false;
 
244
            break;
 
245
        }
 
246
    }
 
247
 
 
248
    CompRect outRect (mAWindow->savedRectsValid () ?
 
249
                      mAWindow->savedOutRect () :
 
250
                      mWindow->outputRect ());
 
251
    CompWindowExtents outExtents (mAWindow->savedRectsValid () ?
 
252
                                  mAWindow->savedOutExtents () :
 
253
                                  mWindow->output ());
 
254
 
 
255
    // window output (contents + decorations + shadows) coordinates and size
 
256
    int ox = outRect.x ();
 
257
    int oy = outRect.y ();
 
258
    int owidth = outRect.width ();
 
259
    int oheight = outRect.height ();
 
260
 
 
261
    // to be used if event is shade/unshade
 
262
    winContentsY = oy + outExtents.top;
 
263
    winContentsHeight = oheight - outExtents.top - outExtents.bottom;
 
264
 
 
265
    geometry.texUnits = (int)nMatrix;
 
266
 
 
267
    if (geometry.vCount == 0)
 
268
    {
 
269
        // reset
 
270
        geometry.indexCount = 0;
 
271
        geometry.texCoordSize = 4;
 
272
    }
 
273
    geometry.vertexStride = 3 + geometry.texUnits * geometry.texCoordSize;
 
274
    vSize = geometry.vertexStride;
 
275
 
 
276
    nVertices = geometry.vCount;
 
277
    nIndices = geometry.indexCount;
 
278
 
 
279
    v = geometry.vertices + (nVertices * vSize);
 
280
    i = geometry.indices + nIndices;
 
281
 
 
282
    // For each clip passed to this function
 
283
    foreach (const CompRect &pClip, region.rects ())
 
284
    {
 
285
        x1 = pClip.x1 ();
 
286
        y1 = pClip.y1 ();
 
287
        x2 = pClip.x2 ();
 
288
        y2 = pClip.y2 ();
 
289
 
 
290
        gridW = (float)owidth / (mGridWidth - 1);
 
291
 
 
292
        if (mCurWindowEvent == WindowEventShade ||
 
293
            mCurWindowEvent == WindowEventUnshade)
 
294
        {
 
295
            if (y1 < winContentsY)      // if at top part
 
296
            {
 
297
                gridH = mDecorTopHeight;
 
298
            }
 
299
            else if (y2 > winContentsY + winContentsHeight)  // if at bottom
 
300
            {
 
301
                gridH = mDecorBottomHeight;
 
302
            }
 
303
            else                        // in window contents (only in Y coords)
 
304
            {
 
305
                float winContentsHeight =
 
306
                    oheight - (mDecorTopHeight + mDecorBottomHeight);
 
307
                gridH = winContentsHeight / (mGridHeight - 3);
 
308
            }
 
309
        }
 
310
        else
 
311
            gridH = (float)oheight / (mGridHeight - 1);
 
312
 
 
313
        // nVertX, nVertY: number of vertices for this clip in x and y dimensions
 
314
        // + 2 to avoid running short of vertices in some cases
 
315
        nVertX = ceil ((x2 - x1) / gridW) + 2;
 
316
        nVertY = (gridH ? ceil ((y2 - y1) / gridH) : 0) + 2;
 
317
 
 
318
        // Allocate 4 indices for each quad
 
319
        int newIndexSize = nIndices + ((nVertX - 1) * (nVertY - 1) * 4);
 
320
 
 
321
        if (newIndexSize > geometry.indexSize)
 
322
        {
 
323
            if (!geometry.moreIndices (newIndexSize))
 
324
                return;
 
325
 
 
326
            i = geometry.indices + nIndices;
 
327
        }
 
328
        // Assign quad vertices to indices
 
329
        for (int jy = 0; jy < nVertY - 1; jy++)
 
330
        {
 
331
            for (int jx = 0; jx < nVertX - 1; jx++)
 
332
            {
 
333
                *i++ = nVertices + nVertX * (2 * jy + 1) + jx;
 
334
                *i++ = nVertices + nVertX * (2 * jy + 1) + jx + 1;
 
335
                *i++ = nVertices + nVertX * 2 * jy + jx + 1;
 
336
                *i++ = nVertices + nVertX * 2 * jy + jx;
 
337
 
 
338
                nIndices += 4;
 
339
            }
 
340
        }
 
341
 
 
342
        // Allocate vertices
 
343
        int newVertexSize =
 
344
            (nVertices + nVertX * (2 * nVertY - 2)) * vSize;
 
345
        if (newVertexSize > geometry.vertexSize)
 
346
        {
 
347
            if (!geometry.moreVertices (newVertexSize))
 
348
                return;
 
349
 
 
350
            v = geometry.vertices + (nVertices * vSize);
 
351
        }
 
352
 
 
353
        float rowTexCoordQ = 1;
 
354
        float prevRowCellWidth = 0;     // this initial value won't be used
 
355
        float rowCellWidth = 0;
 
356
        int clipRowSize = nVertX * vSize;
 
357
 
 
358
        // For each vertex
 
359
        float y = y1;
 
360
        for (int jy = 0; jy < nVertY; jy++)
 
361
        {
 
362
            float topiyFloat;
 
363
            bool applyOffsets = true;
 
364
 
 
365
            if (y > y2)
 
366
                y = y2;
 
367
 
 
368
            // Do calculations for y here to avoid repeating
 
369
            // them unnecessarily in the x loop
 
370
 
 
371
            if (mCurWindowEvent == WindowEventShade ||
 
372
                mCurWindowEvent == WindowEventUnshade)
 
373
            {
 
374
                if (y1 < winContentsY)  // if at top part
 
375
                {
 
376
                    topiyFloat = (y - oy) / mDecorTopHeight;
 
377
                    topiyFloat = MIN (topiyFloat, 0.999);       // avoid 1.0
 
378
                    applyOffsets = false;
 
379
                }
 
380
                else if (y2 > winContentsY + winContentsHeight) // if at bottom
 
381
                {
 
382
                    topiyFloat = (mGridHeight - 2) +
 
383
                        (mDecorBottomHeight ? (y - winContentsY -
 
384
                                               winContentsHeight) /
 
385
                         mDecorBottomHeight : 0);
 
386
                    applyOffsets = false;
 
387
                }
 
388
                else            // in window contents (only in Y coords)
 
389
                {
 
390
                    topiyFloat = (mGridHeight - 3) *
 
391
                        (y - winContentsY) / winContentsHeight + 1;
 
392
                }
 
393
            }
 
394
            else
 
395
            {
 
396
                topiyFloat = (mGridHeight - 1) * (y - oy) / oheight;
 
397
            }
 
398
            // topiy should be at most (mGridHeight - 2)
 
399
            int topiy = (int)(topiyFloat + 1e-4);
 
400
 
 
401
            if (topiy == mGridHeight - 1)
 
402
                topiy--;
 
403
            int bottomiy = topiy + 1;
 
404
            float iny = topiyFloat - topiy;
 
405
            float inyRest = 1 - iny;
 
406
 
 
407
            // End of calculations for y
 
408
 
 
409
            float x = x1;
 
410
            for (int jx = 0; jx < nVertX; jx++)
 
411
            {
 
412
                if (x > x2)
 
413
                    x = x2;
 
414
 
 
415
                // find containing grid cell (leftix rightix) x (topiy bottomiy)
 
416
                float leftixFloat =
 
417
                    (mGridWidth - 1) * (x - ox) / owidth;
 
418
                int leftix = (int)(leftixFloat + 1e-4);
 
419
 
 
420
                if (leftix == mGridWidth - 1)
 
421
                    leftix--;
 
422
                int rightix = leftix + 1;
 
423
 
 
424
                // GridModel::GridObjects that are at top, bottom, left, right corners of quad
 
425
                GridModel::GridObject *objToTopLeft =
 
426
                    &(mModel->mObjects[topiy * mGridWidth + leftix]);
 
427
                GridModel::GridObject *objToTopRight =
 
428
                    &(mModel->mObjects[topiy * mGridWidth + rightix]);
 
429
                GridModel::GridObject *objToBottomLeft =
 
430
                    &(mModel->mObjects[bottomiy * mGridWidth + leftix]);
 
431
                GridModel::GridObject *objToBottomRight =
 
432
                    &(mModel->mObjects[bottomiy * mGridWidth + rightix]);
 
433
 
 
434
                Point3d &objToTopLeftPos = objToTopLeft->mPosition;
 
435
                Point3d &objToTopRightPos = objToTopRight->mPosition;
 
436
                Point3d &objToBottomLeftPos = objToBottomLeft->mPosition;
 
437
                Point3d &objToBottomRightPos = objToBottomRight->mPosition;
 
438
 
 
439
                // find position in cell by taking remainder of flooring
 
440
                float inx = leftixFloat - leftix;
 
441
                float inxRest = 1 - inx;
 
442
 
 
443
                // Interpolate to find deformed coordinates
 
444
 
 
445
                float hor1x = (inxRest * objToTopLeftPos.x () +
 
446
                               inx * objToTopRightPos.x ());
 
447
                float hor1y = (inxRest * objToTopLeftPos.y () +
 
448
                               inx * objToTopRightPos.y ());
 
449
                float hor1z = (notUsing3dCoords ? 0 :
 
450
                               inxRest * objToTopLeftPos.z () +
 
451
                               inx * objToTopRightPos.z ());
 
452
                float hor2x = (inxRest * objToBottomLeftPos.x () +
 
453
                               inx * objToBottomRightPos.x ());
 
454
                float hor2y = (inxRest * objToBottomLeftPos.y () +
 
455
                               inx * objToBottomRightPos.y ());
 
456
                float hor2z = (notUsing3dCoords ? 0 :
 
457
                               inxRest * objToBottomLeftPos.z () +
 
458
                               inx * objToBottomRightPos.z ());
 
459
 
 
460
                deformedX = inyRest * hor1x + iny * hor2x;
 
461
                deformedY = inyRest * hor1y + iny * hor2y;
 
462
                deformedZ = inyRest * hor1z + iny * hor2z;
 
463
 
 
464
                // Texture coordinates (s, t, r, q)
 
465
 
 
466
                if (mUseQTexCoord)
 
467
                {
 
468
                    if (jx == 1)
 
469
                        rowCellWidth = deformedX - v[-3];
 
470
 
 
471
                    // do only once per row for all rows except row 0
 
472
                    if (jy > 0 && jx == 1)
 
473
                    {
 
474
                        rowTexCoordQ = (rowCellWidth / prevRowCellWidth);
 
475
 
 
476
                        for (unsigned int it = 0; it < nMatrix; it++, v += 4)
 
477
                        {
 
478
                            // update first column
 
479
                            // (since we didn't know rowTexCoordQ before)
 
480
                            v[-vSize]     *= rowTexCoordQ; // multiply s & t by q
 
481
                            v[-vSize + 1] *= rowTexCoordQ;
 
482
                            v[-vSize + 3] = rowTexCoordQ;  // copy q
 
483
                        }
 
484
                        v -= nMatrix * 4;
 
485
                    }
 
486
                }
 
487
 
 
488
                // Loop for each texture element
 
489
                // (4 texture coordinates for each one)
 
490
                for (unsigned int it = 0; it < nMatrix; it++, v += 4)
 
491
                {
 
492
                    float offsetY = 0;
 
493
 
 
494
                    if (rect)
 
495
                    {
 
496
                        if (applyOffsets && y < y2)
 
497
                            offsetY = objToTopLeft->mOffsetTexCoordForQuadAfter.y ();
 
498
                        v[0] = COMP_TEX_COORD_X (matrix[it], x); // s
 
499
                        v[1] = COMP_TEX_COORD_Y (matrix[it], y + offsetY); // t
 
500
                    }
 
501
                    else
 
502
                    {
 
503
                        if (applyOffsets && y < y2)
 
504
                            // FIXME:
 
505
                            // The correct y offset below produces wrong
 
506
                            // texture coordinates for some reason.
 
507
                            offsetY = 0;
 
508
                            // offsetY = objToTopLeft->offsetTexCoordForQuadAfter.y;
 
509
                        v[0] = COMP_TEX_COORD_XY (matrix[it], x, y + offsetY); // s
 
510
                        v[1] = COMP_TEX_COORD_YX (matrix[it], x, y + offsetY); // t
 
511
                    }
 
512
                    v[2] = 0; // r
 
513
 
 
514
                    if (0 < jy && jy < nVertY - 1)
 
515
                    {
 
516
                        // copy s, t, r to duplicate row
 
517
                        memcpy (v + clipRowSize, v, 3 * sizeof (GLfloat));
 
518
                        v[3 + clipRowSize] = 1; // q
 
519
                    }
 
520
 
 
521
                    if (applyOffsets &&
 
522
                        objToTopLeft->mOffsetTexCoordForQuadBefore.y () != 0)
 
523
                    {
 
524
                        // After copying to next row, update texture y coord
 
525
                        // by following object's offset
 
526
                        offsetY = objToTopLeft->mOffsetTexCoordForQuadBefore.y ();
 
527
                        if (rect)
 
528
                        {
 
529
                            v[1] = COMP_TEX_COORD_Y (matrix[it], y + offsetY);
 
530
                        }
 
531
                        else
 
532
                        {
 
533
                            v[0] = COMP_TEX_COORD_XY (matrix[it],
 
534
                                                      x, y + offsetY);
 
535
                            v[1] = COMP_TEX_COORD_YX (matrix[it],
 
536
                                                      x, y + offsetY);
 
537
                        }
 
538
                    }
 
539
                    if (mUseQTexCoord)
 
540
                    {
 
541
                        v[3] = rowTexCoordQ; // q
 
542
 
 
543
                        if (jx > 0)     // since column 0 is updated when jx == 1
 
544
                        {
 
545
                            // multiply s & t by q
 
546
                            v[0] *= rowTexCoordQ;
 
547
                            v[1] *= rowTexCoordQ;
 
548
                        }
 
549
                    }
 
550
                    else
 
551
                    {
 
552
                        v[3] = 1; // q
 
553
                    }
 
554
                }
 
555
 
 
556
                v[0] = deformedX;
 
557
                v[1] = deformedY;
 
558
                v[2] = deformedZ;
 
559
 
 
560
                // Copy vertex coordinates to duplicate row
 
561
                if (0 < jy && jy < nVertY - 1)
 
562
                    memcpy (v + clipRowSize, v, 3 * sizeof (GLfloat));
 
563
 
 
564
                nVertices++;
 
565
 
 
566
                // increment x properly (so that coordinates fall on grid intersections)
 
567
                x = rightix * gridW + ox;
 
568
 
 
569
                v += 3; // move on to next vertex
 
570
            }
 
571
            if (mUseQTexCoord)
 
572
                prevRowCellWidth = rowCellWidth;
 
573
 
 
574
            if (0 < jy && jy < nVertY - 1)
 
575
            {
 
576
                v += clipRowSize;       // skip the duplicate row
 
577
                nVertices += nVertX;
 
578
            }
 
579
            // increment y properly (so that coordinates fall on grid intersections)
 
580
            if (mCurWindowEvent == WindowEventShade ||
 
581
                mCurWindowEvent == WindowEventUnshade)
 
582
            {
 
583
                y += gridH;
 
584
            }
 
585
            else
 
586
            {
 
587
                y = bottomiy * gridH + oy;
 
588
            }
 
589
        }
 
590
    }
 
591
    geometry.vCount = nVertices;
 
592
    geometry.indexCount = nIndices;
 
593
}
 
594
 
 
595
void
 
596
GridAnim::drawGeometry ()
 
597
{
 
598
    GLWindow::Geometry &geometry = GLWindow::get (mWindow)->geometry ();
 
599
 
 
600
    int     texUnit = geometry.texUnits;
 
601
    int     currentTexUnit = 0;
 
602
    int     stride = geometry.vertexStride;
 
603
    GLfloat *vertices = geometry.vertices + (stride - 3);
 
604
 
 
605
    stride *= (int) sizeof (GLfloat);
 
606
 
 
607
    glVertexPointer (3, GL_FLOAT, stride, vertices);
 
608
 
 
609
    while (texUnit--)
 
610
    {
 
611
        if (texUnit != currentTexUnit)
 
612
        {
 
613
            (*GL::clientActiveTexture) ((GLenum)(GL_TEXTURE0_ARB + texUnit));
 
614
            glEnableClientState (GL_TEXTURE_COORD_ARRAY);
 
615
            currentTexUnit = texUnit;
 
616
        }
 
617
        vertices -= geometry.texCoordSize;
 
618
        glTexCoordPointer (geometry.texCoordSize,
 
619
                           GL_FLOAT, stride, vertices);
 
620
    }
 
621
 
 
622
    glDrawElements (GL_QUADS, geometry.indexCount,
 
623
                    GL_UNSIGNED_SHORT, geometry.indices);
 
624
 
 
625
    // disable all texture coordinate arrays except 0
 
626
    texUnit = geometry.texUnits;
 
627
    if (texUnit > 1)
 
628
    {
 
629
        while (--texUnit)
 
630
        {
 
631
            (*GL::clientActiveTexture) ((GLenum)(GL_TEXTURE0_ARB + texUnit));
 
632
            glDisableClientState (GL_TEXTURE_COORD_ARRAY);
 
633
        }
 
634
 
 
635
        (*GL::clientActiveTexture) (GL_TEXTURE0_ARB);
 
636
    }
 
637
}
 
638
 
 
639
GridTransformAnim::GridTransformAnim (CompWindow *w,
 
640
                                      WindowEvent curWindowEvent,
 
641
                                      float duration,
 
642
                                      const AnimEffect info,
 
643
                                      const CompRect &icon) :
 
644
    Animation::Animation (w, curWindowEvent, duration, info, icon),
 
645
    TransformAnim::TransformAnim (w, curWindowEvent, duration, info, icon),
 
646
    GridAnim::GridAnim (w, curWindowEvent, duration, info, icon),
 
647
    mUsingTransform (true)
 
648
{
 
649
}
 
650
 
 
651
void
 
652
GridTransformAnim::init ()
 
653
{
 
654
    GridAnim::init ();
 
655
    TransformAnim::init ();
 
656
}
 
657
 
 
658
void
 
659
GridTransformAnim::updateBB (CompOutput &output)
 
660
{
 
661
    if (using3D ())
 
662
    {
 
663
        GLMatrix wTransform;
 
664
 
 
665
        // center for perspective correction
 
666
        Point center = getCenter ();
 
667
 
 
668
        GLMatrix fullTransform (mTransform.getMatrix ());
 
669
        applyPerspectiveSkew (output, fullTransform, center);
 
670
 
 
671
        prepareTransform (output, wTransform, fullTransform);
 
672
 
 
673
        mAWindow->expandBBWithPoints3DTransform (output,
 
674
                                                 wTransform,
 
675
                                                 0,
 
676
                                                 mModel->objects (),
 
677
                                                 mModel->numObjects ());
 
678
    }
 
679
    else
 
680
    {
 
681
        GridModel::GridObject *object = mModel->objects ();
 
682
        unsigned int n = mModel->numObjects ();
 
683
        for (unsigned int i = 0; i < n; i++, object++)
 
684
        {
 
685
            GLVector coords (object->mPosition.x (),
 
686
                             object->mPosition.y (), 0, 1);
 
687
            mAWindow->expandBBWithPoint2DTransform (coords, mTransform);
 
688
        }
 
689
    }
 
690
}
 
691
 
 
692
void
 
693
GridTransformAnim::updateTransform (GLMatrix &wTransform)
 
694
{
 
695
    if (!mUsingTransform)
 
696
        return;
 
697
 
 
698
    TransformAnim::updateTransform (wTransform);
 
699
 
 
700
    if (using3D ())
 
701
    {
 
702
        // center for perspective correction
 
703
        Point center = getCenter ();
 
704
 
 
705
        GLMatrix skewTransform;
 
706
        applyPerspectiveSkew (AnimScreen::get (::screen)->output (),
 
707
                              skewTransform, center);
 
708
        wTransform *= skewTransform;
 
709
    }
 
710
}
 
711