Fix T50736: Zero streaks in Glare node.
[blender.git] / source / blender / compositor / operations / COM_GlareSimpleStarOperation.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor:
19  *              Jeroen Bakker
20  *              Monique Dewanchand
21  */
22
23 #include "COM_GlareSimpleStarOperation.h"
24
25 void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings)
26 {
27         int i, x, y, ym, yp, xm, xp;
28         float c[4] = {0, 0, 0, 0}, tc[4] = {0, 0, 0, 0};
29         const float f1 = 1.0f - settings->fade;
30         const float f2 = (1.0f - f1) * 0.5f;
31
32         MemoryBuffer *tbuf1 = inputTile->duplicate();
33         MemoryBuffer *tbuf2 = inputTile->duplicate();
34
35         bool breaked = false;
36         for (i = 0; i < settings->iter && (!breaked); i++) {
37 //              // (x || x-1, y-1) to (x || x+1, y+1)
38 //              // F
39                 for (y = 0; y < this->getHeight() && (!breaked); y++) {
40                         ym = y - i;
41                         yp = y + i;
42                         for (x = 0; x < this->getWidth(); x++) {
43                                 xm = x - i;
44                                 xp = x + i;
45                                 tbuf1->read(c, x, y);
46                                 mul_v3_fl(c, f1);
47                                 tbuf1->read(tc, (settings->star_45 ? xm : x), ym);
48                                 madd_v3_v3fl(c, tc, f2);
49                                 tbuf1->read(tc, (settings->star_45 ? xp : x), yp);
50                                 madd_v3_v3fl(c, tc, f2);
51                                 c[3] = 1.0f;
52                                 tbuf1->writePixel(x, y, c);
53
54                                 tbuf2->read(c, x, y);
55                                 mul_v3_fl(c, f1);
56                                 tbuf2->read(tc, xm, (settings->star_45 ? yp : y));
57                                 madd_v3_v3fl(c, tc, f2);
58                                 tbuf2->read(tc, xp, (settings->star_45 ? ym : y));
59                                 madd_v3_v3fl(c, tc, f2);
60                                 c[3] = 1.0f;
61                                 tbuf2->writePixel(x, y, c);
62                         }
63                         if (isBreaked()) {
64                                 breaked = true;
65                         }
66                 }
67 //              // B
68                 for (y = tbuf1->getHeight() - 1 && (!breaked); y >= 0; y--) {
69                         ym = y - i;
70                         yp = y + i;
71                         for (x = tbuf1->getWidth() - 1; x >= 0; x--) {
72                                 xm = x - i;
73                                 xp = x + i;
74                                 tbuf1->read(c, x, y);
75                                 mul_v3_fl(c, f1);
76                                 tbuf1->read(tc, (settings->star_45 ? xm : x), ym);
77                                 madd_v3_v3fl(c, tc, f2);
78                                 tbuf1->read(tc, (settings->star_45 ? xp : x), yp);
79                                 madd_v3_v3fl(c, tc, f2);
80                                 c[3] = 1.0f;
81                                 tbuf1->writePixel(x, y, c);
82
83                                 tbuf2->read(c, x, y);
84                                 mul_v3_fl(c, f1);
85                                 tbuf2->read(tc, xm, (settings->star_45 ? yp : y));
86                                 madd_v3_v3fl(c, tc, f2);
87                                 tbuf2->read(tc, xp, (settings->star_45 ? ym : y));
88                                 madd_v3_v3fl(c, tc, f2);
89                                 c[3] = 1.0f;
90                                 tbuf2->writePixel(x, y, c);
91                         }
92                         if (isBreaked()) {
93                                 breaked = true;
94                         }
95                 }
96         }
97
98         for (i = 0; i < this->getWidth() * this->getHeight() * 4; i++) {
99                 data[i] = tbuf1->getBuffer()[i] + tbuf2->getBuffer()[i];
100         }
101
102         delete tbuf1;
103         delete tbuf2;
104 }