~mc-return/compiz/compiz.merge-firepaint-improvements

« back to all changes in this revision

Viewing changes to plugins/firepaint/src/firepaint.cpp

  • Committer: MC Return
  • Date: 2013-07-04 15:07:44 UTC
  • Revision ID: mc.return@gmx.net-20130704150744-59nsmoed1slemood
Firepaint, multiple improvements
(please see main commit message for details)

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
COMPIZ_PLUGIN_20090315 (firepaint, FirePluginVTable);
25
25
 
26
26
/* 3 vertices per triangle, 2 triangles per particle */
27
 
const unsigned short CACHESIZE_FACTOR = 3 * 2;
28
 
 
 
27
const unsigned short CACHESIZE_FACTOR  = 3 * 2;
29
28
/* 2 coordinates, x and y */
30
 
const unsigned short COORD_COMPONENTS = CACHESIZE_FACTOR * 2;
31
 
 
 
29
const unsigned short COORD_COMPONENTS  = CACHESIZE_FACTOR * 2;
32
30
/* each vertex is stored as 3 GLfloats */
33
31
const unsigned short VERTEX_COMPONENTS = CACHESIZE_FACTOR * 3;
34
 
 
35
32
/* 4 colors, RGBA */
36
 
const unsigned short COLOR_COMPONENTS = CACHESIZE_FACTOR * 4;
 
33
const unsigned short COLOR_COMPONENTS  = CACHESIZE_FACTOR * 4;
37
34
 
38
35
Particle::Particle () :
39
 
    life (0),
40
 
    fade (0),
41
 
    width (0),
 
36
    life   (0),
 
37
    fade   (0),
 
38
    width  (0),
42
39
    height (0),
43
 
    w_mod (0),
44
 
    h_mod (0),
45
 
    r (0),
46
 
    g (0),
47
 
    b (0),
48
 
    a (0),
49
 
    x (0),
50
 
    y (0),
51
 
    z (0),
52
 
    xi (0),
53
 
    yi (0),
54
 
    zi (0),
55
 
    xg (0),
56
 
    yg (0),
57
 
    zg (0),
58
 
    xo (0),
59
 
    yo (0),
60
 
    zo (0)
 
40
    w_mod  (0),
 
41
    h_mod  (0),
 
42
    r      (0),
 
43
    g      (0),
 
44
    b      (0),
 
45
    a      (0),
 
46
    x      (0),
 
47
    y      (0),
 
48
    z      (0),
 
49
    xi     (0),
 
50
    yi     (0),
 
51
    zi     (0),
 
52
    xg     (0),
 
53
    yg     (0),
 
54
    zg     (0),
 
55
    xo     (0),
 
56
    yo     (0),
 
57
    zo     (0)
61
58
{
62
59
}
63
60
 
81
78
}
82
79
 
83
80
void
84
 
ParticleSystem::initParticles (int            f_numParticles)
 
81
ParticleSystem::initParticles (int f_numParticles)
85
82
{
86
83
    particles.clear ();
87
84
 
88
 
    tex = 0;
 
85
    tex      = 0;
89
86
    slowdown = 1;
90
 
    active = false;
91
 
    darken = 0;
 
87
    active   = false;
 
88
    darken   = 0;
92
89
 
93
90
    // Initialize cache
94
91
    vertices_cache.clear ();
96
93
    colors_cache.clear ();
97
94
    dcolors_cache.clear ();
98
95
 
99
 
    for (int i = 0; i < f_numParticles; i++)
 
96
    for (int i = 0; i < f_numParticles; ++i)
100
97
    {
101
98
        Particle p;
102
99
        p.life = 0.0f;
105
102
}
106
103
 
107
104
void
108
 
ParticleSystem::drawParticles(const GLMatrix         &transform)
 
105
ParticleSystem::drawParticles(const GLMatrix &transform)
109
106
{
110
107
    int i, j, k, l;
111
108
 
123
120
        if (dcolors_cache.size () < particles.size () * COLOR_COMPONENTS)
124
121
            dcolors_cache.resize (particles.size () * COLOR_COMPONENTS);
125
122
 
126
 
    glEnable (GL_BLEND);
 
123
    GLboolean glBlendEnabled = glIsEnabled (GL_BLEND);
 
124
 
 
125
    if (!glBlendEnabled)
 
126
        glEnable (GL_BLEND);
127
127
 
128
128
    if (tex)
129
129
    {
133
133
 
134
134
    i = j = k = l = 0;
135
135
 
 
136
    GLfloat w, h;
 
137
    GLfloat xMinusW, xPlusW, yMinusH, yPlusH;
 
138
    GLushort r, g, b, a, dark_a;
 
139
 
136
140
    /* for each particle, use two triangles to display it */
137
141
    foreach (Particle &part, particles) 
138
142
    {
139
143
        if (part.life > 0.0f)
140
144
        {
141
 
            float w = part.width / 2;
142
 
            float h = part.height / 2;
143
 
 
144
 
            GLushort r, g, b, a, dark_a;
 
145
            w = part.width  / 2.0f;
 
146
            h = part.height / 2.0f;
145
147
 
146
148
            r = part.r * 65535.0f;
147
149
            g = part.g * 65535.0f;
148
150
            b = part.b * 65535.0f;
149
 
            a = part.life * part.a * 65535.0f;
150
 
            dark_a = part.life * part.a * darken * 65535.0f;
151
 
 
152
 
            w += (w * part.w_mod) * part.life;
153
 
            h += (h * part.h_mod) * part.life;
 
151
            a      = part.life * part.a * 65535.0f;
 
152
            dark_a = part.life * part.a * 65535.0f * darken;
 
153
 
 
154
            w += w * part.w_mod * part.life;
 
155
            h += h * part.h_mod * part.life;
 
156
 
 
157
            xMinusW = part.x - w;
 
158
            xPlusW  = part.x + w;
 
159
 
 
160
            yMinusH = part.y - h;
 
161
            yPlusH  = part.y + h;
154
162
 
155
163
            //first triangle
156
 
            vertices_cache[i + 0] = part.x - w;
157
 
            vertices_cache[i + 1] = part.y - h;
 
164
            vertices_cache[i + 0] = xMinusW;
 
165
            vertices_cache[i + 1] = yMinusH;
158
166
            vertices_cache[i + 2] = part.z;
159
167
 
160
 
            vertices_cache[i + 3] = part.x - w;
161
 
            vertices_cache[i + 4] = part.y + h;
 
168
            vertices_cache[i + 3] = xMinusW;
 
169
            vertices_cache[i + 4] = yPlusH;
162
170
            vertices_cache[i + 5] = part.z;
163
171
 
164
 
            vertices_cache[i + 6] = part.x + w;
165
 
            vertices_cache[i + 7] = part.y + h;
 
172
            vertices_cache[i + 6] = xPlusW;
 
173
            vertices_cache[i + 7] = yPlusH;
166
174
            vertices_cache[i + 8] = part.z;
167
175
 
168
176
            //second triangle
169
 
            vertices_cache[i + 9] = part.x + w;
170
 
            vertices_cache[i + 10] = part.y + h;
 
177
            vertices_cache[i + 9] = xPlusW;
 
178
            vertices_cache[i + 10] = yPlusH;
171
179
            vertices_cache[i + 11] = part.z;
172
180
 
173
 
            vertices_cache[i + 12] = part.x + w;
174
 
            vertices_cache[i + 13] = part.y - h;
 
181
            vertices_cache[i + 12] = xPlusW;
 
182
            vertices_cache[i + 13] = yMinusH;
175
183
            vertices_cache[i + 14] = part.z;
176
184
 
177
 
            vertices_cache[i + 15] = part.x - w;
178
 
            vertices_cache[i + 16] = part.y - h;
 
185
            vertices_cache[i + 15] = xMinusW;
 
186
            vertices_cache[i + 16] = yMinusH;
179
187
            vertices_cache[i + 17] = part.z;
180
188
 
181
189
            i += 18;
271
279
            }
272
280
        }
273
281
    }
274
 
    
 
282
 
275
283
    GLVertexBuffer *stream = GLVertexBuffer::streamingBuffer ();
276
284
 
277
285
    if (darken > 0)
303
311
}
304
312
 
305
313
void
306
 
ParticleSystem::updateParticles (float          time)
 
314
ParticleSystem::updateParticles (float time)
307
315
{
308
 
    float speed = (time / 50.0);
309
 
    float f_slowdown = slowdown * (1 - MAX (0.99, time / 1000.0) ) * 1000;
 
316
    float speed      = (time / 50.0);
 
317
    float f_slowdown = slowdown * (1 - MAX (0.99, time / 1000.0)) * 1000;
310
318
 
311
319
    active = false;
312
320
 
351
359
}
352
360
 
353
361
void
354
 
FireScreen::fireAddPoint (int        x,
355
 
                          int        y,
356
 
                          bool       requireGrab)
 
362
FireScreen::fireAddPoint (int  x,
 
363
                          int  y,
 
364
                          bool requireGrab)
357
365
{
358
 
 
359
366
    if (!requireGrab || grabIndex)
360
367
    {
361
368
        XPoint p;
366
373
        points.push_back (p);
367
374
 
368
375
        toggleFunctions (true);
369
 
 
370
376
    }
371
 
 
372
377
}
373
378
 
374
379
bool
376
381
                         CompAction::State  state,
377
382
                         CompOption::Vector options)
378
383
{
379
 
    float x, y;
380
 
 
381
 
    x = CompOption::getFloatOptionNamed (options, "x", 0);
382
 
    y = CompOption::getFloatOptionNamed (options, "y", 0);
 
384
    float x = CompOption::getFloatOptionNamed (options, "x", 0);
 
385
    float y = CompOption::getFloatOptionNamed (options, "y", 0);
383
386
 
384
387
    fireAddPoint (x, y, false);
385
388
 
394
397
                      CompOption::Vector options)
395
398
{
396
399
    if (screen->otherGrabExist (NULL))
397
 
        return false;
 
400
        return false;
398
401
 
399
402
    if (!grabIndex)
400
 
        grabIndex = screen->pushGrab (None, "firepaint");
 
403
        grabIndex = screen->pushGrab (None, "firepaint");
401
404
 
402
405
    if (state & CompAction::StateInitButton)
403
 
        action->setState (action->state () | CompAction::StateTermButton);
 
406
        action->setState (action->state () | CompAction::StateTermButton);
404
407
 
405
408
    if (state & CompAction::StateInitKey)
406
 
        action->setState (action->state () | CompAction::StateTermKey);
 
409
        action->setState (action->state () | CompAction::StateTermKey);
407
410
 
408
411
    fireAddPoint (pointerX, pointerY, true);
409
412
 
415
418
                       CompAction::State  state,
416
419
                       CompOption::Vector options)
417
420
{
418
 
 
419
421
    if (grabIndex)
420
422
    {
421
423
        screen->removeGrab (grabIndex, NULL);
423
425
    }
424
426
 
425
427
    action->setState (action->state () & ~(CompAction::StateTermKey |
426
 
                                           CompAction::StateTermButton));
427
 
 
 
428
                                           CompAction::StateTermButton));
428
429
    return false;
429
430
}
430
431
 
438
439
}
439
440
 
440
441
void
441
 
FireScreen::preparePaint (int      time)
 
442
FireScreen::preparePaint (int time)
442
443
{
443
444
    float bg = (float) optionGetBgBrightness () / 100.0;
444
445
 
460
461
        ps.slowdown  = optionGetFireSlowdown ();
461
462
        ps.darken    = 0.5;
462
463
        ps.blendMode = GL_ONE;
463
 
 
464
464
    }
465
465
 
466
466
    if (!init)
468
468
 
469
469
    if (!points.empty ())
470
470
    {
 
471
        int   rVal2;
 
472
        float rVal, size = 4;
471
473
        float max_new = MIN ((int) ps.particles.size (),  (int) points.size () * 2) *
472
474
                        ((float) time / 50.0) *
473
475
                        (1.05 - optionGetFireLife());
474
 
        float rVal, size = 4;
475
 
        int rVal2;
476
476
 
477
 
        for (unsigned int i = 0;
478
 
             i < ps.particles.size () && max_new > 0; i++)
 
477
        for (unsigned int i = 0; i < ps.particles.size () && max_new > 0; ++i)
479
478
        {
480
479
            Particle &part = ps.particles.at (i);
 
480
 
481
481
            if (part.life <= 0.0f)
482
482
            {
483
483
                /* give gt new life */
485
485
                part.life = 1.0f;
486
486
                /* Random Fade Value */
487
487
                part.fade = (rVal * (1 - optionGetFireLife ()) +
488
 
                              (0.2f * (1.01 - optionGetFireLife ())));
 
488
                             (0.2f * (1.01 - optionGetFireLife ())));
489
489
 
490
490
                /* set size */
491
491
                part.width  = optionGetFireSize ();
523
523
                }
524
524
                else
525
525
                {
526
 
                    part.r = (float) optionGetFireColorRed () / 0xffff -
527
 
                              (rVal / 1.7 *
528
 
                               (float) optionGetFireColorRed () / 0xffff);
529
 
                    part.g = (float) optionGetFireColorGreen () / 0xffff -
530
 
                              (rVal / 1.7 *
531
 
                              (float) optionGetFireColorGreen () / 0xffff);
532
 
                    part.b = (float) optionGetFireColorBlue () / 0xffff -
533
 
                              (rVal / 1.7 *
534
 
                              (float) optionGetFireColorBlue () / 0xffff);
 
526
                    part.r = optionGetFireColorRed () / 0xffff -
 
527
                             (rVal / 1.7 * optionGetFireColorRed () / 0xffff);
 
528
                    part.g = optionGetFireColorGreen () / 0xffff -
 
529
                             (rVal / 1.7 * optionGetFireColorGreen () / 0xffff);
 
530
                    part.b = optionGetFireColorBlue () / 0xffff -
 
531
                             (rVal / 1.7 * optionGetFireColorBlue () / 0xffff);
535
532
                }
536
533
 
537
534
                /* set transparency */
547
544
                max_new -= 1;
548
545
            }
549
546
            else
550
 
            {
551
547
                part.xg = (part.x < part.xo) ? 1.0 : -1.0;
552
 
            }
553
548
        }
554
549
    }
555
550
 
558
553
        float div = 1.0 - bg;
559
554
        div *= (float) time / 500.0;
560
555
        brightness = MAX (bg, brightness - div);
561
 
 
562
556
    }
563
557
 
564
558
    if (points.empty () && brightness != 1.0)
566
560
        float div = 1.0 - bg;
567
561
        div *= (float) time / 500.0;
568
562
        brightness = MIN (1.0, brightness + div);
569
 
 
570
563
    }
571
564
 
572
565
    if (!init && points.empty () && !ps.active)
580
573
 
581
574
bool
582
575
FireScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
583
 
                           const GLMatrix            &transform,
584
 
                           const CompRegion          &region,
585
 
                           CompOutput                *output,
586
 
                           unsigned int              mask)
 
576
                           const GLMatrix            &transform,
 
577
                           const CompRegion          &region,
 
578
                           CompOutput                *output,
 
579
                           unsigned int              mask)
587
580
{
588
 
    bool status;
589
 
 
590
 
    status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
591
 
 
592
 
    if ( (!init && ps.active) || brightness < 1.0)
 
581
    bool status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
 
582
 
 
583
    if ((!init && ps.active) || brightness < 1.0)
593
584
    {
594
585
        GLMatrix sTransform = transform;
595
586
 
600
591
            /* cover the screen with a rectangle and darken it
601
592
             * (coded as two GL_TRIANGLES for GLES compatibility)
602
593
             */
603
 
 
604
594
            GLfloat vertices[18];
605
595
            GLushort colors[24];
606
596
 
628
618
            vertices[16] = (GLfloat)output->region ()->extents.y1;
629
619
            vertices[17] = 0.0f;
630
620
 
631
 
            for (int i = 0; i <= 5; i++)
 
621
            for (int i = 0; i <= 5; ++i)
632
622
            {
633
623
                colors[i*4+0] = 0;
634
624
                colors[i*4+1] = 0;
636
626
                colors[i*4+3] = (1.0 - brightness) * 65535.0f;
637
627
            }
638
628
 
639
 
            GLVertexBuffer *stream = GLVertexBuffer::streamingBuffer ();
640
 
            glEnable (GL_BLEND);
 
629
            GLVertexBuffer *stream        = GLVertexBuffer::streamingBuffer ();
 
630
            GLboolean      glBlendEnabled = glIsEnabled (GL_BLEND);
 
631
 
 
632
            if (!glBlendEnabled)
 
633
                glEnable (GL_BLEND);
 
634
 
641
635
            stream->begin (GL_TRIANGLES);
642
636
            stream->addVertices (6, vertices);
643
637
            stream->addColors (6, colors);
650
644
 
651
645
        if (!init && ps.active)
652
646
            ps.drawParticles (sTransform);
653
 
 
654
647
    }
655
648
 
656
649
    return status;
660
653
FireScreen::donePaint ()
661
654
{
662
655
    if ( (!init && ps.active) || !points.empty () || brightness < 1.0)
663
 
    {
664
656
        cScreen->damageScreen ();
665
 
    }
666
657
    else
667
658
        toggleFunctions (false);
668
659
 
674
665
{
675
666
    switch (event->type)
676
667
    {
677
 
 
678
668
    case MotionNotify:
679
669
        fireAddPoint (pointerX, pointerY, true);
680
670
        break;
682
672
    case EnterNotify:
683
673
    case LeaveNotify:
684
674
        fireAddPoint (pointerX, pointerY, true);
 
675
        break;
 
676
 
685
677
    default:
686
678
        break;
687
679
    }