Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: samplecode/SampleAndroidShadows.cpp

Issue 2249973003: Add alternative ambient shadow method to Android shadow sample (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fixup distance vector usage Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2016 Google Inc. 3 * Copyright 2016 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "SampleCode.h" 8 #include "SampleCode.h"
9 #include "SkBlurMask.h" 9 #include "SkBlurMask.h"
10 #include "SkBlurMaskFilter.h" 10 #include "SkBlurMaskFilter.h"
11 #include "SkCanvas.h" 11 #include "SkCanvas.h"
12 #include "SkGaussianEdgeShader.h"
12 #include "SkPath.h" 13 #include "SkPath.h"
13 #include "SkPoint3.h" 14 #include "SkPoint3.h"
14 #include "SkUtils.h" 15 #include "SkUtils.h"
15 #include "SkView.h" 16 #include "SkView.h"
16 #include "sk_tool_utils.h" 17 #include "sk_tool_utils.h"
17 18
19 ////////////////////////////////////////////////////////////////////////////
20
18 class ShadowsView : public SampleView { 21 class ShadowsView : public SampleView {
19 SkPath fRectPath; 22 SkPath fRectPath;
20 SkPath fRRPath; 23 SkPath fRRPath;
21 SkPath fCirclePath; 24 SkPath fCirclePath;
22 SkPoint3 fLightPos; 25 SkPoint3 fLightPos;
23 26
24 bool fShowAmbient; 27 bool fShowAmbient;
28 bool fUseAltAmbient;
25 bool fShowSpot; 29 bool fShowSpot;
26 bool fShowObject; 30 bool fShowObject;
27 31
28 public: 32 public:
29 ShadowsView() 33 ShadowsView()
30 : fShowAmbient(true) 34 : fShowAmbient(true)
35 , fUseAltAmbient(true)
31 , fShowSpot(true) 36 , fShowSpot(true)
32 , fShowObject(true) {} 37 , fShowObject(true) {}
33 38
34 protected: 39 protected:
35 void onOnceBeforeDraw() override { 40 void onOnceBeforeDraw() override {
36 fCirclePath.addCircle(0, 0, 50); 41 fCirclePath.addCircle(0, 0, 50);
37 fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100)); 42 fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100));
38 fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 10 0), 4, 4)); 43 fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 10 0), 4, 4));
39 fLightPos = SkPoint3::Make(-220, -330, 150); 44 fLightPos = SkPoint3::Make(-220, -330, 150);
40 } 45 }
41 46
42 // overrides from SkEventSink 47 // overrides from SkEventSink
43 bool onQuery(SkEvent* evt) override { 48 bool onQuery(SkEvent* evt) override {
44 if (SampleCode::TitleQ(*evt)) { 49 if (SampleCode::TitleQ(*evt)) {
45 SampleCode::TitleR(evt, "AndroidShadows"); 50 SampleCode::TitleR(evt, "AndroidShadows");
46 return true; 51 return true;
47 } 52 }
48 53
49 SkUnichar uni; 54 SkUnichar uni;
50 if (SampleCode::CharQ(*evt, &uni)) { 55 if (SampleCode::CharQ(*evt, &uni)) {
51 switch (uni) { 56 switch (uni) {
52 case 'B': 57 case 'B':
53 fShowAmbient = !fShowAmbient; 58 fShowAmbient = !fShowAmbient;
54 break; 59 break;
60 case 'T':
61 fUseAltAmbient = !fUseAltAmbient;
62 break;
55 case 'S': 63 case 'S':
56 fShowSpot = !fShowSpot; 64 fShowSpot = !fShowSpot;
57 break; 65 break;
58 case 'O': 66 case 'O':
59 fShowObject = !fShowObject; 67 fShowObject = !fShowObject;
60 break; 68 break;
61 case '>': 69 case '>':
62 fLightPos.fZ += 10; 70 fLightPos.fZ += 10;
63 break; 71 break;
64 case '<': 72 case '<':
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 occlRect, 121 occlRect,
114 SkBlurMaskFilter::kNone_ BlurFlag); 122 SkBlurMaskFilter::kNone_ BlurFlag);
115 123
116 SkPaint paint; 124 SkPaint paint;
117 paint.setAntiAlias(true); 125 paint.setAntiAlias(true);
118 paint.setMaskFilter(std::move(mf)); 126 paint.setMaskFilter(std::move(mf));
119 paint.setColor(SkColorSetARGB((unsigned char)(ambientAlpha*umbraAlpha*25 5.999f), 0, 0, 0)); 127 paint.setColor(SkColorSetARGB((unsigned char)(ambientAlpha*umbraAlpha*25 5.999f), 0, 0, 0));
120 canvas->drawPath(path, paint); 128 canvas->drawPath(path, paint);
121 129
122 // draw occlusion rect 130 // draw occlusion rect
131 #if DRAW_OCCL_RECT
123 SkPaint stroke; 132 SkPaint stroke;
124 stroke.setStyle(SkPaint::kStroke_Style); 133 stroke.setStyle(SkPaint::kStroke_Style);
125 stroke.setColor(SK_ColorBLUE); 134 stroke.setColor(SK_ColorBLUE);
126 canvas->drawRect(occlRect, stroke); 135 canvas->drawRect(occlRect, stroke);
136 #endif
137 }
138
139 void drawAmbientShadowAlt(SkCanvas* canvas, const SkPath& path, SkScalar zVa lue,
140 SkScalar ambientAlpha) {
141
142 if (ambientAlpha <= 0) {
143 return;
144 }
145
146 const SkScalar kHeightFactor = 1.f / 128.f;
147 const SkScalar kGeomFactor = 64;
148
149 SkScalar umbraAlpha = 1 / (1 + SkMaxScalar(zValue*kHeightFactor, 0));
150 SkScalar radius = zValue*kHeightFactor*kGeomFactor;
151
152 // fast path
153 SkRect pathRect;
154 SkRRect pathRRect;
155 if ((path.isOval(&pathRect) && pathRect.width() == pathRect.height()) ||
156 (path.isRRect(&pathRRect) && pathRRect.allCornersCircular()) ||
157 path.isRect(&pathRect)) {
158
159 // For all of these, we outset the rect by half the radius to get ou r stroke shape.
160 if (path.isOval(nullptr)) {
161 pathRect.outset(0.5f*radius, 0.5f*radius);
162 pathRRect = SkRRect::MakeOval(pathRect);
163 } else if (path.isRect(nullptr)) {
164 pathRect.outset(0.5f*radius, 0.5f*radius);
165 pathRRect = SkRRect::MakeRectXY(pathRect, 0.5f*radius, 0.5f*radi us);
166 } else {
167 pathRRect.outset(0.5f*radius, 0.5f*radius);
168 }
169
170 SkPaint paint;
171 paint.setAntiAlias(true);
172 paint.setColor(SkColorSetARGB((unsigned char)(ambientAlpha*umbraAlph a*255.999f),
173 0, 0, 0));
174 paint.setStrokeWidth(radius);
175 paint.setStyle(SkPaint::kStroke_Style);
176
robertphillips 2016/08/16 21:25:42 do we need std::move here ? Can't we just say "pa
jvanverth1 2016/08/16 21:31:19 Done.
177 sk_sp<SkShader> gaussShader = std::move(SkGaussianEdgeShader::Make() );
178 paint.setShader(gaussShader);
179 canvas->drawRRect(pathRRect, paint);
180 } else {
181 // occlude blur
182 SkRect occlRect;
183 GetOcclRect(path, &occlRect);
184 sk_sp<SkMaskFilter> f = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
185 SkBlurMask::ConvertRa diusToSigma(radius),
186 occlRect,
187 SkBlurMaskFilter::kNo ne_BlurFlag);
188
189 SkPaint paint;
190 paint.setAntiAlias(true);
191 paint.setMaskFilter(std::move(f));
192 paint.setColor(SkColorSetARGB((unsigned char)(ambientAlpha*umbraAlph a*255.999f),
193 0, 0, 0));
194 canvas->drawPath(path, paint);
195
196 // draw occlusion rect
197 #if DRAW_OCCL_RECT
198 SkPaint stroke;
199 stroke.setStyle(SkPaint::kStroke_Style);
200 stroke.setColor(SK_ColorBLUE);
201 canvas->drawRect(occlRect, stroke);
202 #endif
203 }
204
127 } 205 }
128 206
129 void drawSpotShadow(SkCanvas* canvas, const SkPath& path, SkScalar zValue, 207 void drawSpotShadow(SkCanvas* canvas, const SkPath& path, SkScalar zValue,
130 SkPoint3 lightPos, SkScalar lightWidth, SkScalar spotAlp ha) { 208 SkPoint3 lightPos, SkScalar lightWidth, SkScalar spotAlp ha) {
131 if (spotAlpha <= 0) { 209 if (spotAlpha <= 0) {
132 return; 210 return;
133 } 211 }
134 212
135 SkScalar zRatio = zValue / (lightPos.fZ - zValue); 213 SkScalar zRatio = zValue / (lightPos.fZ - zValue);
136 if (zRatio < 0.0f) { 214 if (zRatio < 0.0f) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 paint.setAntiAlias(true); 249 paint.setAntiAlias(true);
172 paint.setMaskFilter(std::move(mf)); 250 paint.setMaskFilter(std::move(mf));
173 paint.setColor(SkColorSetARGB((unsigned char)(spotAlpha*255.999f), 0, 0, 0)); 251 paint.setColor(SkColorSetARGB((unsigned char)(spotAlpha*255.999f), 0, 0, 0));
174 252
175 // apply transformation to shadow 253 // apply transformation to shadow
176 canvas->translate(offset.fX, offset.fY); 254 canvas->translate(offset.fX, offset.fY);
177 canvas->scale(scale, scale); 255 canvas->scale(scale, scale);
178 canvas->drawPath(path, paint); 256 canvas->drawPath(path, paint);
179 257
180 // draw occlusion rect 258 // draw occlusion rect
259 #if DRAW_OCCL_RECT
181 SkPaint stroke; 260 SkPaint stroke;
182 stroke.setStyle(SkPaint::kStroke_Style); 261 stroke.setStyle(SkPaint::kStroke_Style);
183 stroke.setColor(SK_ColorRED); 262 stroke.setColor(SK_ColorRED);
184 canvas->drawRect(occlRect, stroke); 263 canvas->drawRect(occlRect, stroke)
264 #endif
185 } 265 }
186 266
187 void drawShadowedPath(SkCanvas* canvas, const SkPath& path, SkScalar zValue, 267 void drawShadowedPath(SkCanvas* canvas, const SkPath& path, SkScalar zValue,
188 const SkPaint& paint) { 268 const SkPaint& paint) {
189 const SkScalar kLightWidth = 3; 269 const SkScalar kLightWidth = 3;
190 const SkScalar kAmbientAlpha = 0.25f; 270 const SkScalar kAmbientAlpha = 0.25f;
191 const SkScalar kSpotAlpha = 0.25f; 271 const SkScalar kSpotAlpha = 0.25f;
192 272
193 if (fShowAmbient) { 273 if (fShowAmbient) {
194 this->drawAmbientShadow(canvas, path, zValue, kAmbientAlpha); 274 if (fUseAltAmbient) {
275 this->drawAmbientShadowAlt(canvas, path, zValue, kAmbientAlpha);
276 } else {
277 this->drawAmbientShadow(canvas, path, zValue, kAmbientAlpha);
278 }
195 } 279 }
196 if (fShowSpot) { 280 if (fShowSpot) {
197 this->drawSpotShadow(canvas, path, zValue, fLightPos, kLightWidth, k SpotAlpha); 281 this->drawSpotShadow(canvas, path, zValue, fLightPos, kLightWidth, k SpotAlpha);
198 } 282 }
199 if (fShowObject) { 283 if (fShowObject) {
200 canvas->drawPath(path, paint); 284 canvas->drawPath(path, paint);
201 } 285 }
202 } 286 }
203 287
204 void onDrawContent(SkCanvas* canvas) override { 288 void onDrawContent(SkCanvas* canvas) override {
205 this->drawBG(canvas); 289 this->drawBG(canvas);
206 290
207 SkPaint paint; 291 SkPaint paint;
208 paint.setAntiAlias(true); 292 paint.setAntiAlias(true);
209 293
210 paint.setColor(SK_ColorWHITE); 294 paint.setColor(SK_ColorWHITE);
211 canvas->translate(200, 90); 295 canvas->translate(200, 90);
212 this->drawShadowedPath(canvas, fRectPath, 5, paint); 296 this->drawShadowedPath(canvas, fRectPath, 5, paint);
213 297
214 paint.setColor(SK_ColorRED); 298 paint.setColor(SK_ColorRED);
215 canvas->translate(250, 0); 299 canvas->translate(250, 0);
216 this->drawShadowedPath(canvas, fRRPath, 5, paint); 300 this->drawShadowedPath(canvas, fRRPath, 5, paint);
217 301
218 paint.setColor(SK_ColorBLUE); 302 paint.setColor(SK_ColorBLUE);
219 canvas->translate(-250, 110); 303 canvas->translate(-250, 110);
220 this->drawShadowedPath(canvas, fCirclePath, 5, paint); 304 this->drawShadowedPath(canvas, fCirclePath, 5, paint);
305
306 paint.setColor(SK_ColorGREEN);
307 canvas->translate(250, 0);
308 this->drawShadowedPath(canvas, fRRPath, 5, paint);
221 } 309 }
222 310
223 protected: 311 protected:
224 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) ove rride { 312 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) ove rride {
225 return new SkView::Click(this); 313 return new SkView::Click(this);
226 } 314 }
227 315
228 bool onClick(Click *click) override { 316 bool onClick(Click *click) override {
229 SkScalar x = click->fCurr.fX; 317 SkScalar x = click->fCurr.fX;
230 SkScalar y = click->fCurr.fY; 318 SkScalar y = click->fCurr.fY;
(...skipping 11 matching lines...) Expand all
242 } 330 }
243 331
244 private: 332 private:
245 typedef SkView INHERITED; 333 typedef SkView INHERITED;
246 }; 334 };
247 335
248 ////////////////////////////////////////////////////////////////////////////// 336 //////////////////////////////////////////////////////////////////////////////
249 337
250 static SkView* MyFactory() { return new ShadowsView; } 338 static SkView* MyFactory() { return new ShadowsView; }
251 static SkViewRegister reg(MyFactory); 339 static SkViewRegister reg(MyFactory);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698