~vanvugt/compiz-plugins-main/fix-915236

« back to all changes in this revision

Viewing changes to animation/src/grid.cpp

  • Committer: Sam Spilsbury
  • Date: 2011-08-12 06:36:10 UTC
  • Revision ID: sam.spilsbury@canonical.com-20110812063610-8mcxo2xohctyp2ak
Sync - Remove Plugins

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