|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include "HuiFxVg10HSLFilter.h" |
|
21 #include <math.h> |
|
22 #include "HuiFxConstants.h" |
|
23 |
|
24 // local helper functions |
|
25 static void getSaturationRotationMatrix(VGfloat *effectMatrix, const VGfloat opacity, const VGfloat angle, const VGfloat saturation); |
|
26 static void getSaturationMatrix(VGfloat *effectMatrix, const VGfloat opacity, const VGfloat saturation); |
|
27 static void getRotationMatrix(VGfloat *effectMatrix, const VGfloat opacity, const VGfloat angle); |
|
28 static void getIdentityMatrix(VGfloat *effectMatrix); |
|
29 |
|
30 CHuiFxVg10HSLFilter* CHuiFxVg10HSLFilter::NewL() |
|
31 { |
|
32 CHuiFxVg10HSLFilter* e = new (ELeave) CHuiFxVg10HSLFilter(); |
|
33 CleanupStack::PushL(e); |
|
34 e->ConstructL(); |
|
35 CleanupStack::Pop(e); |
|
36 return e; |
|
37 } |
|
38 |
|
39 void CHuiFxVg10HSLFilter::ConstructL() |
|
40 { |
|
41 CHuiFxVg10ColorMatrixFilterBase::ConstructL(); |
|
42 // neutral settings |
|
43 iHue = 0.0f; // 0.0f to 360.0f, neutral: 0.0f |
|
44 iSaturation = 1.0f; // 0.0f to 100.0f, neutral: 1.0f |
|
45 iLightness = 0.0f; // -1.0f to 1.0f, neutral: 0.0f |
|
46 RegisterParameterL(KLitHue, &iHue); |
|
47 RegisterParameterL(KLitSaturation, &iSaturation); |
|
48 RegisterParameterL(KLitLightness, &iLightness); |
|
49 } |
|
50 CHuiFxVg10HSLFilter *CHuiFxVg10HSLFilter::CloneL() const |
|
51 { |
|
52 CHuiFxVg10HSLFilter *filter = new (ELeave) CHuiFxVg10HSLFilter; |
|
53 filter->CHuiFxVg10ColorMatrixFilterBase::CopyFromL(this); |
|
54 filter->iHue = iHue; |
|
55 filter->iSaturation = iSaturation; |
|
56 filter->iLightness = iLightness; |
|
57 filter->CopyParameterL(KLitHue, &filter->iHue, this); |
|
58 filter->CopyParameterL(KLitSaturation, &filter->iSaturation, this); |
|
59 filter->CopyParameterL(KLitLightness, &filter->iLightness, this); |
|
60 return filter; |
|
61 } |
|
62 |
|
63 // |
|
64 // Background for HSL matrices can be found at http://www.opengl.org/resources/code/samples/advanced/advanced97/notes/node137.html |
|
65 // |
|
66 void CHuiFxVg10HSLFilter::UpdateColorMatrix(void) |
|
67 { |
|
68 // a helpful constant |
|
69 const VGfloat radsPerDeg = 2.0f * (float)M_PI / 360.0f; |
|
70 |
|
71 // make sure parametres are in range |
|
72 const VGfloat opacity = clamp(iOpacity, 0.0f, 1.0f); |
|
73 const VGfloat angle = clamp(iHue * radsPerDeg, 0.0f, 2.0f * (float)M_PI); // angle [0, 2*pi] |
|
74 const VGfloat saturation = clamp(iSaturation, 0.0f, 100.0f); // saturation [0, N] |
|
75 const VGfloat lightness = clamp(iLightness, -1.0f, 1.0f); // lightness [-1, 1] |
|
76 |
|
77 // check parametres which precalculated matrix we have to use. |
|
78 // Note: lightness affects offset and not matrix so we don't bother optimising that. |
|
79 const bool enableSaturation = (saturation < 1.0f - EPSILON || saturation > 1.0f + EPSILON); |
|
80 const bool enableHueRotation = (EPSILON < angle && angle < (2.0f * (float)M_PI - EPSILON)); |
|
81 |
|
82 if(enableSaturation && enableHueRotation) |
|
83 { |
|
84 // contains SaturateT*PrerotationT*HuerotationT*PostrotationT*I*opacity+I*(1-opacity) matrices --- ugly, but saves lot of operations in FPU. |
|
85 // note: there are plenty of redundancy in these calculations --- let compiler optimise them. |
|
86 getSaturationRotationMatrix(&iColorMatrix[0], opacity, saturation, angle); |
|
87 } |
|
88 else if(enableSaturation && !enableHueRotation) |
|
89 { |
|
90 // saturationT*I*opacity+I*(1 - opacity) matrix without hue rotation |
|
91 getSaturationMatrix(&iColorMatrix[0], opacity, saturation); |
|
92 } |
|
93 else if(!enableSaturation && enableHueRotation) |
|
94 { |
|
95 // PrerotationT*HuerotationT*PostrotationT*I*opacity+I*(1-opacity) matrices without saturation matrix |
|
96 getRotationMatrix(&iColorMatrix[0], opacity, angle); |
|
97 } |
|
98 else |
|
99 { |
|
100 // identity matrix |
|
101 getIdentityMatrix(&iColorMatrix[0]); |
|
102 } |
|
103 |
|
104 // colour component offsets |
|
105 iColorMatrix[16] = lightness * opacity; |
|
106 iColorMatrix[17] = lightness * opacity; |
|
107 iColorMatrix[18] = lightness * opacity; |
|
108 iColorMatrix[19] = 0.0f; |
|
109 } |
|
110 |
|
111 |
|
112 static void getSaturationRotationMatrix(VGfloat *effectMatrix, const VGfloat opacity, const VGfloat saturation, const VGfloat angle) |
|
113 { |
|
114 const VGfloat sa = saturation; |
|
115 const VGfloat as = 1.0f - saturation; |
|
116 |
|
117 const VGfloat o = opacity; |
|
118 const VGfloat ao = 1.0f - o; |
|
119 |
|
120 const VGfloat c = cos(angle); |
|
121 const VGfloat s = sin(angle); |
|
122 |
|
123 effectMatrix[0] = o * ((-0.02473f*as+0.66667f*sa)*c+ (0.30450f*as*s+(0.33333f*as+0.33333f*sa))) + ao; |
|
124 effectMatrix[1] = o * ((-0.02473f*as-0.33333f*sa)*c+((0.30450f*as+0.57736f*sa)*s+(0.33333f*as+0.33333f*sa))); |
|
125 effectMatrix[2] = o * ((-0.02473f*as-0.33333f*sa)*c+((0.30450f*as-0.57736f*sa)*s+(0.33333f*as+0.33333f*sa))); |
|
126 effectMatrix[3] = 0.0f; |
|
127 effectMatrix[4] = o * ((0.27607f*as-0.33333f*sa)*c+((-0.13083f*as-0.57736f*sa)*s+(0.33333f*as+0.33333f*sa))); |
|
128 effectMatrix[5] = o * ((0.27607f*as+0.66667f*sa)*c+ (-0.13083f*as*s+(0.33333f*as+0.33333f*sa))) + ao; |
|
129 effectMatrix[6] = o * ((0.27607f*as-0.33333f*sa)*c+((-0.13083f*as+0.57736f*sa)*s+(0.33333f*as+0.33333f*sa))); |
|
130 effectMatrix[7] = 0.0f; |
|
131 effectMatrix[8] = o * ((-0.25134f*as-0.33333f*sa)*c+((-0.17367f*as+0.57736f*sa)*s+(0.33333f*as+0.33333f*sa))); |
|
132 effectMatrix[9] = o * ((-0.25134f*as-0.33333f*sa)*c+((-0.17367f*as-0.57736f*sa)*s+(0.33333f*as+0.33333f*sa))); |
|
133 effectMatrix[10] = o * ((-0.25134f*as+0.66667f*sa)*c+ (-0.17367f*as*s+(0.33333f*as+0.33333f*sa))) + ao; |
|
134 effectMatrix[11] = 0.0f; |
|
135 effectMatrix[12] = 0.0f; |
|
136 effectMatrix[13] = 0.0f; |
|
137 effectMatrix[14] = 0.0f; |
|
138 effectMatrix[15] = 1.0f; |
|
139 } |
|
140 |
|
141 |
|
142 static void getSaturationMatrix(VGfloat *effectMatrix, const VGfloat opacity, const VGfloat saturation) |
|
143 { |
|
144 const VGfloat Rw = 0.3086f; |
|
145 const VGfloat Gw = 0.6094f; |
|
146 const VGfloat Bw = 0.0820f; |
|
147 |
|
148 const VGfloat sa = saturation; |
|
149 const VGfloat as = 1.0f - saturation; |
|
150 |
|
151 const VGfloat o = opacity; |
|
152 const VGfloat ao = 1.0f - o; |
|
153 |
|
154 const VGfloat asRw = o * as * Rw; |
|
155 const VGfloat asGw = o * as * Gw; |
|
156 const VGfloat asBw = o * as * Bw; |
|
157 |
|
158 effectMatrix[0] = asRw + sa + ao; |
|
159 effectMatrix[1] = asRw; |
|
160 effectMatrix[2] = asRw; |
|
161 effectMatrix[3] = 0.0f; |
|
162 effectMatrix[4] = asGw; |
|
163 effectMatrix[5] = asGw + sa + ao; |
|
164 effectMatrix[6] = asGw; |
|
165 effectMatrix[7] = 0.0f; |
|
166 effectMatrix[8] = asBw; |
|
167 effectMatrix[9] = asBw; |
|
168 effectMatrix[10] = asBw + sa + ao; |
|
169 effectMatrix[11] = 0.0f; |
|
170 effectMatrix[12] = 0.0f; |
|
171 effectMatrix[13] = 0.0f; |
|
172 effectMatrix[14] = 0.0f; |
|
173 effectMatrix[15] = 1.0f; |
|
174 } |
|
175 |
|
176 |
|
177 static void getRotationMatrix(VGfloat *effectMatrix, const VGfloat opacity, const VGfloat angle) |
|
178 { |
|
179 const VGfloat o = opacity; |
|
180 const VGfloat ao = 1.0f - o; |
|
181 |
|
182 const VGfloat c = cos(angle); |
|
183 const VGfloat s = sin(angle); |
|
184 |
|
185 effectMatrix[0] = o * ( 0.66667f*c+0.33333f) + ao; |
|
186 effectMatrix[1] = o * (-0.33333f*c+(0.57736f*s+0.33333f)); |
|
187 effectMatrix[2] = o * (-0.33333f*c+(-0.57736f*s+0.33333f)); |
|
188 effectMatrix[3] = 0.0f; |
|
189 effectMatrix[4] = o * (-0.33333f*c+(-0.57736f*s+0.33333f)); |
|
190 effectMatrix[5] = o * ( 0.66667f*c+0.33333f) + ao; |
|
191 effectMatrix[6] = o * (-0.33333f*c+(0.57736f*s+0.33333f)); |
|
192 effectMatrix[7] = 0.0f; |
|
193 effectMatrix[8] = o * (-0.33333f*c+(0.57736f*s+0.33333f)); |
|
194 effectMatrix[9] = o * (-0.33333f*c+(-0.57736f*s+0.33333f)); |
|
195 effectMatrix[10] = o * (0.66667f*c+0.33333f) + ao; |
|
196 effectMatrix[11] = 0.0f; |
|
197 effectMatrix[12] = 0.0f; |
|
198 effectMatrix[13] = 0.0f; |
|
199 effectMatrix[14] = 0.0f; |
|
200 effectMatrix[15] = 1.0f; |
|
201 } |
|
202 |
|
203 |
|
204 static void getIdentityMatrix(VGfloat *effectMatrix) |
|
205 { |
|
206 effectMatrix[0] = 1.0f; |
|
207 effectMatrix[1] = 0.0f; |
|
208 effectMatrix[2] = 0.0f; |
|
209 effectMatrix[3] = 0.0f; |
|
210 effectMatrix[4] = 0.0f; |
|
211 effectMatrix[5] = 1.0f; |
|
212 effectMatrix[6] = 0.0f; |
|
213 effectMatrix[7] = 0.0f; |
|
214 effectMatrix[8] = 0.0f; |
|
215 effectMatrix[9] = 0.0f; |
|
216 effectMatrix[10] = 1.0f; |
|
217 effectMatrix[11] = 0.0f; |
|
218 effectMatrix[12] = 0.0f; |
|
219 effectMatrix[13] = 0.0f; |
|
220 effectMatrix[14] = 0.0f; |
|
221 effectMatrix[15] = 1.0f; |
|
222 } |