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

Side by Side Diff: samplecode/SampleAndroidShadows.cpp

Issue 2245693002: Add Android Shadow sample (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix line lengths 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
« no previous file with comments | « gyp/samples.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
2 /*
robertphillips 2016/08/12 15:55:01 time warp
jvanverth1 2016/08/12 16:43:43 Done.
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8 #include "SampleCode.h"
9 #include "SkBlurMask.h"
10 #include "SkBlurMaskFilter.h"
11 #include "SkCanvas.h"
12 #include "SkPath.h"
13 #include "SkPoint3.h"
14 #include "SkUtils.h"
15 #include "SkView.h"
16 #include "sk_tool_utils.h"
17
18 class ShadowsView : public SampleView {
19 SkPath fRectPath;
20 SkPath fRRPath;
21 SkPath fCirclePath;
robertphillips 2016/08/12 15:55:01 Do we use these last 3 ?
jvanverth1 2016/08/12 16:43:43 Done.
22 SkPath fOvalPath;
23 SkPath fConvexPath;
24 SkPath fConcavePath;
25 SkPoint3 fLightPos;
26
27 bool fShowAmbient;
28 bool fShowSpot;
29 bool fShowObject;
30
31 public:
32 ShadowsView() {}
33
34 protected:
35 void onOnceBeforeDraw() override {
36 fCirclePath.addCircle(0, 0, 50);
37 fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100));
38 fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 10 0), 4, 4));
39 fLightPos = SkPoint3::Make(-220, -330, 256);
robertphillips 2016/08/12 15:55:01 I feel we should init the bools in the ctor
jvanverth1 2016/08/12 16:43:43 Done.
40 fShowAmbient = fShowSpot = fShowObject = true;
41 }
42
43 // overrides from SkEventSink
44 bool onQuery(SkEvent* evt) override {
45 if (SampleCode::TitleQ(*evt)) {
46 SampleCode::TitleR(evt, "AndroidShadows");
47 return true;
48 }
49
50 SkUnichar uni;
51 if (SampleCode::CharQ(*evt, &uni)) {
52 switch (uni) {
53 case 'B':
54 fShowAmbient = !fShowAmbient;
55 break;
56 case 'S':
57 fShowSpot = !fShowSpot;
58 break;
59 case 'O':
60 fShowObject = !fShowObject;
61 break;
62 default:
63 break;
64 }
65 this->inval(nullptr);
66 }
67 return this->INHERITED::onQuery(evt);
68 }
69
70 void drawBG(SkCanvas* canvas) {
71 canvas->drawColor(0xFFDDDDDD);
72 }
73
robertphillips 2016/08/12 15:55:01 move out of class or make GetOcclRect ?
jvanverth1 2016/08/12 16:43:43 Done.
74 static void get_occl_rect(const SkPath& path, SkRect* occlRect) {
75 SkRect pathRect;
76 SkRRect pathRRect;
77 if (path.isOval(&pathRect)) {
78 *occlRect = sk_tool_utils::compute_central_occluder(SkRRect::MakeOva l(pathRect));
79 } else if (path.isRRect(&pathRRect)) {
80 *occlRect = sk_tool_utils::compute_central_occluder(pathRRect);
81 } else if (!path.isRect(occlRect)) {
82 *occlRect = SkRect::MakeEmpty();
83 }
84 }
85
86 void drawAmbientShadow(SkCanvas* canvas, const SkPath& path, SkScalar zValue ,
87 SkScalar ambientAlpha) {
88
89 if (ambientAlpha <= 0) {
90 return;
91 }
92
93 const SkScalar kHeightFactor = 1.f / 128.f;
94 const SkScalar kGeomFactor = 64;
95
96 SkScalar umbraAlpha = 1 / (1 + SkMaxScalar(zValue*kHeightFactor, 0));
97 SkScalar radius = zValue*kHeightFactor*kGeomFactor;
98
99 // occlude blur
100 SkRect occlRect;
101 get_occl_rect(path, &occlRect);
102 sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
103 SkBlurMask::ConvertRadiu sToSigma(radius),
104 occlRect,
105 SkBlurMaskFilter::kNone_ BlurFlag);
106
107 SkPaint paint;
108 paint.setAntiAlias(true);
robertphillips 2016/08/12 15:55:01 std::move(mf) ?
jvanverth1 2016/08/12 16:43:43 Done.
109 paint.setMaskFilter(mf);
110 paint.setColor(SkColorSetARGB((unsigned char)(ambientAlpha*umbraAlpha*25 5.999f), 0, 0, 0));
111 canvas->drawPath(path, paint);
112
113 // draw occlusion rect
114 SkPaint stroke;
115 stroke.setStyle(SkPaint::kStroke_Style);
116 stroke.setColor(SK_ColorBLUE);
117 canvas->drawRect(occlRect, stroke);
118 }
119
120 void drawSpotShadow(SkCanvas* canvas, const SkPath& path, SkScalar zValue,
121 SkPoint3 lightPos, SkScalar lightWidth, SkScalar spotAlp ha) {
122 if (spotAlpha <= 0) {
123 return;
124 }
125
126 SkScalar zRatio = zValue / (lightPos.fZ - zValue);
127 if (zRatio < 0.0f) {
128 zRatio = 0.0f;
129 } else if (zRatio > 0.95f) {
130 zRatio = 0.95f;
131 }
132 SkScalar radius = lightWidth*zRatio;
133
134 // compute the transformation params
135 SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBound s().centerY());
136 canvas->getTotalMatrix().mapPoints(&center, 1);
137 SkPoint offset = SkPoint::Make(-zRatio*(lightPos.fX - center.fX),
138 -zRatio*(lightPos.fY - center.fY));
139 SkScalar scale = lightPos.fZ / (lightPos.fZ - zValue);
140 if (scale < 1.0f) {
141 scale = 1.0f;
142 } else if (scale > 1024.f) {
143 scale = 1024.f;
144 }
145
146 SkAutoCanvasRestore acr(canvas, true);
147
148 SkRect occlRect;
149 get_occl_rect(path, &occlRect);
robertphillips 2016/08/12 15:55:01 Is this explicit xform necessary? occlRect should
jvanverth1 2016/08/12 16:43:43 Yes, it is (though the xform needs to be scale, th
150 // apply inverse transform
151 occlRect.offset(-offset);
152 occlRect.fLeft /= scale;
153 occlRect.fRight /= scale;
154 occlRect.fTop /= scale;
155 occlRect.fBottom /= scale;
156 sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
157 SkBlurMask::ConvertRadiu sToSigma(radius),
158 occlRect,
159 SkBlurMaskFilter::kNone_ BlurFlag);
160
161 SkPaint paint;
162 paint.setAntiAlias(true);
robertphillips 2016/08/12 15:55:01 here too ?
jvanverth1 2016/08/12 16:43:43 Done.
163 paint.setMaskFilter(mf);
164 paint.setColor(SkColorSetARGB((unsigned char)(spotAlpha*255.999f), 0, 0, 0));
165
166 // apply transformation to shadow
167 canvas->scale(scale, scale);
168 canvas->translate(offset.fX, offset.fY);
169 canvas->drawPath(path, paint);
170
171 // draw occlusion rect
172 SkPaint stroke;
173 stroke.setStyle(SkPaint::kStroke_Style);
174 stroke.setColor(SK_ColorRED);
175 canvas->drawRect(occlRect, stroke);
176 }
177
178 void drawShadowedPath(SkCanvas* canvas, const SkPath& path, SkScalar zValue,
179 const SkPaint& paint) {
180 const SkScalar kLightWidth = 3;
181 const SkScalar kAmbientAlpha = 0.25f;
182 const SkScalar kSpotAlpha = 0.25f;
183
184 if (fShowAmbient) {
robertphillips 2016/08/12 15:55:01 this-> ?
jvanverth1 2016/08/12 16:43:43 Done.
185 drawAmbientShadow(canvas, path, zValue, kAmbientAlpha);
186 }
187 if (fShowSpot) {
robertphillips 2016/08/12 15:55:01 Here too ?
jvanverth1 2016/08/12 16:43:43 Done.
188 drawSpotShadow(canvas, path, zValue, fLightPos, kLightWidth, kSpotAl pha);
189 }
190 if (fShowObject) {
191 canvas->drawPath(path, paint);
192 }
193 }
194
195 void onDrawContent(SkCanvas* canvas) override {
robertphillips 2016/08/12 15:55:01 this-> ?
jvanverth1 2016/08/12 16:43:43 Done.
196 drawBG(canvas);
197
198 SkPaint paint;
199 paint.setAntiAlias(true);
200
201 paint.setColor(SK_ColorBLUE);
202 canvas->translate(200, 200);
robertphillips 2016/08/12 15:55:01 ?
jvanverth1 2016/08/12 16:43:43 Done.
203 drawShadowedPath(canvas, fCirclePath, 5, paint);
204
205 paint.setColor(SK_ColorWHITE);
206 canvas->translate(0, -110);
207 drawShadowedPath(canvas, fRectPath, 5, paint);
208
209 paint.setColor(SK_ColorRED);
210 canvas->translate(250, 0);
211 drawShadowedPath(canvas, fRRPath, 5, paint);
212 }
213
214 protected:
215 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) ove rride {
216 return new SkView::Click(this);
217 }
218
219 bool onClick(Click *click) override {
220 SkScalar x = click->fCurr.fX;
221 SkScalar y = click->fCurr.fY;
222
223 SkScalar dx = x - click->fPrev.fX;
224 SkScalar dy = y - click->fPrev.fY;
225
226 if (dx != 0 || dy != 0) {
227 fLightPos.fX += dx;
228 fLightPos.fY += dy;
229 this->inval(nullptr);
230 }
231
232 return true;
233 }
234
235 private:
236 typedef SkView INHERITED;
237 };
238
239 //////////////////////////////////////////////////////////////////////////////
240
241 static SkView* MyFactory() { return new ShadowsView; }
242 static SkViewRegister reg(MyFactory);
OLDNEW
« no previous file with comments | « gyp/samples.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698