7
* Copyright : (C) 2006-2010 by Patrick Niklaus, Roi Cohen,
8
* Danny Baumann, Sam Spilsbury
9
* Authors: Patrick Niklaus <patrick.niklaus@googlemail.com>
10
* Roi Cohen <roico.beryl@gmail.com>
11
* Danny Baumann <maniac@opencompositing.org>
12
* Sam Spilsbury <smspillaz@gmail.com>
15
* This program is free software; you can redistribute it and/or
16
* modify it under the terms of the GNU General Public License
17
* as published by the Free Software Foundation; either version 2
18
* of the License, or (at your option) any later version.
20
* This program is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
* GNU General Public License for more details.
28
#include "group_glow.h"
30
const GlowTextureProperties glowTextureProperties = {
31
/* GlowTextureRectangular */
36
* GroupWindow::paintGlow
38
* Takes our glow texture, stretches the appropriate positions in the glow texture,
39
* adds those geometries (so plugins like wobby and deform this texture correctly)
40
* and then draws the glow texture with this geometry (plugins like wobbly and friends
41
* will automatically deform the texture based on our set geometry)
45
ExpoWindow::paintGlow (GLFragment::Attrib &attrib,
46
const CompRegion &paintRegion,
52
/* There are 8 glow parts of the glow texture which we wish to paint
53
* separately with different transformations
55
for (i = 0; i < NUM_GLOWQUADS; i++)
57
/* Using precalculated quads here */
58
reg = CompRegion (mGlowQuads[i].mBox);
60
if (reg.boundingRect ().x1 () < reg.boundingRect ().x2 () &&
61
reg.boundingRect ().y1 () < reg.boundingRect ().y2 ())
63
GLTexture::MatrixList matl;
64
reg = CompRegion (reg.boundingRect ().x1 (),
65
reg.boundingRect ().y1 (),
66
reg.boundingRect ().width (),
67
reg.boundingRect ().height ());
69
matl.push_back (mGlowQuads[i].mMatrix);
70
gWindow->glAddGeometry (matl, reg, paintRegion);
74
/* If the geometry add succeeded */
75
if (gWindow->geometry ().vertices)
77
GLFragment::Attrib fAttrib (attrib);
79
GLushort color[3] = {MAXSHORT,
83
float alpha = (float) ExpoScreen::get (screen)->optionGetSelectedColorAlpha () / 65535.0f;
85
GLScreen::get (screen)->setTexEnvMode (GL_MODULATE);
86
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
87
glColor4f (((float) ExpoScreen::get (screen)->optionGetSelectedColorRed () / 65535.0f) * alpha,
88
((float) ExpoScreen::get (screen)->optionGetSelectedColorGreen () / 65535.0f) * alpha,
89
((float) ExpoScreen::get (screen)->optionGetSelectedColorBlue () / 65535.0f) * alpha,
92
/* we use PAINT_WINDOW_TRANSFORMED_MASK here to force
93
the usage of a good texture filter */
94
foreach (GLTexture *tex, ExpoScreen::get (screen)->outline_texture)
96
gWindow->glDrawTexture (tex, fAttrib, mask |
97
PAINT_WINDOW_BLEND_MASK |
98
PAINT_WINDOW_TRANSLUCENT_MASK |
99
PAINT_WINDOW_TRANSFORMED_MASK);
102
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
103
GLScreen::get (screen)->setTexEnvMode (GL_REPLACE);
104
glColor4usv (defaultColor);
109
* ExpoWindow::computeGlowQuads
111
* This function computures the matrix transformation required for each
112
* part of the glow texture which we wish to stretch to some rectangular
115
* There are eight quads different parts of the texture which we wish to
116
* paint here, the 4 sides and four corners, eg:
120
* ------------- ------------------
121
* | 1 | 4 | 6 | | | | |
122
* ------------- | | | |
123
* | 2 | n | 7 | -> | 2 | n | 7 |
124
* ------------- | | | |
125
* | 3 | 5 | 8 | | | | |
126
* ------------- ------------------
130
* In this example here, 2, 4, 5 and 7 are stretched, and the matrices for
131
* each quad rect adjusted accordingly for it's size compared to the original
134
* When we are adjusting the matrices here, the initial size of each corner has
135
* a size of of "1.0f", so according to 2x2 matrix rules,
136
* the scale factor is the inverse of the size of the glow (which explains
137
* while you will see here that matrix->xx is (1 / glowSize)
138
* where glowSize is the size the user specifies they want their glow to extend.
139
* (likewise, matrix->yy is adjusted similarly for corners and for top/bottom)
141
* matrix->x0 and matrix->y0 here are set to be the top left edge of the rect
142
* adjusted by the matrix scale factor (matrix->xx and matrix->yy)
146
ExpoWindow::computeGlowQuads (GLTexture::Matrix *matrix)
150
GLTexture::Matrix *quadMatrix;
151
int glowSize, glowOffset;
152
CompWindow *w = window;
154
/* Passing NULL to this function frees the glow quads
155
* (so the window is not painted with glow) */
160
mGlowQuads = new GlowQuad[NUM_GLOWQUADS];
175
glowOffset = (glowSize * ExpoScreen::get (screen)->mGlowTextureProperties->glowOffset /
176
ExpoScreen::get (screen)->mGlowTextureProperties->textureSize) + 1;
178
/* Top left corner */
179
box = &mGlowQuads[GLOWQUAD_TOPLEFT].mBox;
180
mGlowQuads[GLOWQUAD_TOPLEFT].mMatrix = *matrix;
181
quadMatrix = &mGlowQuads[GLOWQUAD_TOPLEFT].mMatrix;
183
/* Set the desired rect dimentions
184
* for the part of the glow we are painting */
186
x1 = WIN_REAL_X (w) - glowSize + glowOffset;
187
y1 = WIN_REAL_Y (w) - glowSize + glowOffset;
189
/* 2x2 Matrix here, adjust both x and y scale factors
190
* and the x and y position
192
* Scaling both parts of the texture in a positive direction
193
* here (left to right top to bottom)
195
* The base position (x0 and y0) here requires us to move backwards
196
* on the x and y dimentions by the calculated rect dimentions
197
* multiplied by the scale factors
200
quadMatrix->xx = 1.0f / glowSize;
201
quadMatrix->yy = 1.0f / (glowSize);
202
quadMatrix->x0 = -(x1 * quadMatrix->xx);
203
quadMatrix->y0 = -(y1 * quadMatrix->yy);
205
x2 = MIN (WIN_REAL_X (w) + glowOffset,
206
WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
207
y2 = MIN (WIN_REAL_Y (w) + glowOffset,
208
WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));
210
*box = CompRect (x1, y1, x2 - x1, y2 - y1);
212
/* Top right corner */
213
box = &mGlowQuads[GLOWQUAD_TOPRIGHT].mBox;
214
mGlowQuads[GLOWQUAD_TOPRIGHT].mMatrix = *matrix;
215
quadMatrix = &mGlowQuads[GLOWQUAD_TOPRIGHT].mMatrix;
217
/* Set the desired rect dimentions
218
* for the part of the glow we are painting */
220
x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
221
y1 = WIN_REAL_Y (w) - glowSize + glowOffset;
222
x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset;
224
/* 2x2 Matrix here, adjust both x and y scale factors
225
* and the x and y position
227
* Scaling the y part of the texture in a positive direction
228
* and the x part in a negative direction here
229
* (right to left top to bottom)
231
* The base position (x0 and y0) here requires us to move backwards
232
* on the y dimention and forwards on x by the calculated rect dimentions
233
* multiplied by the scale factors (since we are moving forward on x we
234
* need the inverse of that which is 1 - x1 * xx
237
quadMatrix->xx = -1.0f / glowSize;
238
quadMatrix->yy = 1.0f / glowSize;
239
quadMatrix->x0 = 1.0 - (x1 * quadMatrix->xx);
240
quadMatrix->y0 = -(y1 * quadMatrix->yy);
242
x1 = MAX (WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset,
243
WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
244
y2 = MIN (WIN_REAL_Y (w) + glowOffset,
245
WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));
247
*box = CompRect (x1, y1, x2 - x1, y2 - y1);
249
/* Bottom left corner */
250
box = &mGlowQuads[GLOWQUAD_BOTTOMLEFT].mBox;
251
mGlowQuads[GLOWQUAD_BOTTOMLEFT].mMatrix = *matrix;
252
quadMatrix = &mGlowQuads[GLOWQUAD_BOTTOMLEFT].mMatrix;
254
x1 = WIN_REAL_X (w) - glowSize + glowOffset;
255
y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
256
x2 = WIN_REAL_X (w) + glowOffset;
257
y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset;
259
/* 2x2 Matrix here, adjust both x and y scale factors
260
* and the x and y position
262
* Scaling the x part of the texture in a positive direction
263
* and the y part in a negative direction here
264
* (left to right bottom to top)
266
* The base position (x0 and y0) here requires us to move backwards
267
* on the x dimention and forwards on y by the calculated rect dimentions
268
* multiplied by the scale factors (since we are moving forward on x we
269
* need the inverse of that which is 1 - y1 * yy
272
quadMatrix->xx = 1.0f / glowSize;
273
quadMatrix->yy = -1.0f / glowSize;
274
quadMatrix->x0 = -(x1 * quadMatrix->xx);
275
quadMatrix->y0 = 1.0f - (y1 * quadMatrix->yy);
277
y1 = MAX (WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset,
278
WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));
279
x2 = MIN (WIN_REAL_X (w) + glowOffset,
280
WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
282
*box = CompRect (x1, y1, x2 - x1, y2 - y1);
284
/* Bottom right corner */
285
box = &mGlowQuads[GLOWQUAD_BOTTOMRIGHT].mBox;
286
mGlowQuads[GLOWQUAD_BOTTOMRIGHT].mMatrix = *matrix;
287
quadMatrix = &mGlowQuads[GLOWQUAD_BOTTOMRIGHT].mMatrix;
289
x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
290
y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
291
x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset;
292
y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset;
294
/* 2x2 Matrix here, adjust both x and y scale factors
295
* and the x and y position
297
* Scaling the both parts of the texture in a negative direction
298
* (right to left bottom to top)
300
* The base position (x0 and y0) here requires us to move forwards
301
* on both dimentions by the calculated rect dimentions
302
* multiplied by the scale factors
305
quadMatrix->xx = -1.0f / glowSize;
306
quadMatrix->yy = -1.0f / glowSize;
307
quadMatrix->x0 = 1.0 - (x1 * quadMatrix->xx);
308
quadMatrix->y0 = 1.0 - (y1 * quadMatrix->yy);
310
x1 = MAX (WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset,
311
WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
312
y1 = MAX (WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset,
313
WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));
315
*box = CompRect (x1, y1, x2 - x1, y2 - y1);
318
box = &mGlowQuads[GLOWQUAD_TOP].mBox;
319
mGlowQuads[GLOWQUAD_TOP].mMatrix = *matrix;
320
quadMatrix = &mGlowQuads[GLOWQUAD_TOP].mMatrix;
322
x1 = WIN_REAL_X (w) + glowOffset;
323
y1 = WIN_REAL_Y (w) - glowSize + glowOffset;
324
x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
325
y2 = WIN_REAL_Y (w) + glowOffset;
327
/* 2x2 Matrix here, adjust both x and y scale factors
328
* and the x and y position
330
* No need to scale the x part of the texture here, but we
331
* are scaling on the y part in a positive direciton
333
* The base position (y0) here requires us to move backwards
334
* on the x dimention and forwards on y by the calculated rect dimentions
335
* multiplied by the scale factors
338
quadMatrix->xx = 0.0f;
339
quadMatrix->yy = 1.0f / glowSize;
340
quadMatrix->x0 = 1.0;
341
quadMatrix->y0 = -(y1 * quadMatrix->yy);
343
*box = CompRect (x1, y1, x2 - x1, y2 - y1);
346
box = &mGlowQuads[GLOWQUAD_BOTTOM].mBox;
347
mGlowQuads[GLOWQUAD_BOTTOM].mMatrix = *matrix;
348
quadMatrix = &mGlowQuads[GLOWQUAD_BOTTOM].mMatrix;
350
x1 = WIN_REAL_X (w) + glowOffset;
351
y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
352
x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
353
y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset;
355
/* 2x2 Matrix here, adjust both x and y scale factors
356
* and the x and y position
358
* No need to scale the x part of the texture here, but we
359
* are scaling on the y part in a negative direciton
361
* The base position (y0) here requires us to move forwards
362
* on y by the calculated rect dimentions
363
* multiplied by the scale factors
366
quadMatrix->xx = 0.0f;
367
quadMatrix->yy = -1.0f / glowSize;
368
quadMatrix->x0 = 1.0;
369
quadMatrix->y0 = 1.0 - (y1 * quadMatrix->yy);
371
*box = CompRect (x1, y1, x2 - x1, y2 - y1);
374
box = &mGlowQuads[GLOWQUAD_LEFT].mBox;
375
mGlowQuads[GLOWQUAD_LEFT].mMatrix = *matrix;
376
quadMatrix = &mGlowQuads[GLOWQUAD_LEFT].mMatrix;
378
x1 = WIN_REAL_X (w) - glowSize + glowOffset;
379
y1 = WIN_REAL_Y (w) + glowOffset;
380
x2 = WIN_REAL_X (w) + glowOffset;
381
y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
383
/* 2x2 Matrix here, adjust both x and y scale factors
384
* and the x and y position
386
* No need to scale the y part of the texture here, but we
387
* are scaling on the x part in a positive direciton
389
* The base position (x0) here requires us to move backwards
390
* on x by the calculated rect dimentions
391
* multiplied by the scale factors
394
quadMatrix->xx = 1.0f / glowSize;
395
quadMatrix->yy = 0.0f;
396
quadMatrix->x0 = -(x1 * quadMatrix->xx);
397
quadMatrix->y0 = 1.0;
399
*box = CompRect (x1, y1, x2 - x1, y2 - y1);
402
box = &mGlowQuads[GLOWQUAD_RIGHT].mBox;
403
mGlowQuads[GLOWQUAD_RIGHT].mMatrix = *matrix;
404
quadMatrix = &mGlowQuads[GLOWQUAD_RIGHT].mMatrix;
406
x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
407
y1 = WIN_REAL_Y (w) + glowOffset;
408
x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset;
409
y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
411
/* 2x2 Matrix here, adjust both x and y scale factors
412
* and the x and y position
414
* No need to scale the y part of the texture here, but we
415
* are scaling on the x part in a negative direciton
417
* The base position (x0) here requires us to move forwards
418
* on x by the calculated rect dimentions
419
* multiplied by the scale factors
422
quadMatrix->xx = -1.0f / glowSize;
423
quadMatrix->yy = 0.0f;
424
quadMatrix->x0 = 1.0 - (x1 * quadMatrix->xx);
425
quadMatrix->y0 = 1.0;
427
*box = CompRect (x1, y1, x2 - x1, y2 - y1);