blob: c8ce14c8d5a2700f8cca6248a40853db9bf1abc1 [file] [log] [blame]
jvanverthe1a3bc62016-08-12 10:40:38 -07001
2/*
3 * Copyright 2016 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"
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -05009#include "SkAnimTimer.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070010#include "SkBlurMask.h"
11#include "SkBlurMaskFilter.h"
Jim Van Verth2aa535e2017-02-06 14:36:01 -050012#include "SkColorFilter.h"
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050013#include "SkCamera.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070014#include "SkCanvas.h"
jvanverth6c177a12016-08-17 07:59:41 -070015#include "SkGaussianEdgeShader.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070016#include "SkPath.h"
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050017#include "SkPathOps.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070018#include "SkPoint3.h"
Jim Van Verth43475ad2017-01-13 14:37:37 -050019#include "SkShadowUtils.h"
jvanverthe1a3bc62016-08-12 10:40:38 -070020#include "SkUtils.h"
21#include "SkView.h"
22#include "sk_tool_utils.h"
23
jvanverth6c177a12016-08-17 07:59:41 -070024////////////////////////////////////////////////////////////////////////////
25
jvanverthe1a3bc62016-08-12 10:40:38 -070026class ShadowsView : public SampleView {
27 SkPath fRectPath;
28 SkPath fRRPath;
29 SkPath fCirclePath;
Jim Van Verthbce74962017-01-25 09:39:46 -050030 SkPath fFunkyRRPath;
31 SkPath fCubicPath;
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050032 SkPath fSquareRRectPath;
33 SkPath fWideRectPath;
34 SkPath fWideOvalPath;
jvanverthe1a3bc62016-08-12 10:40:38 -070035 SkPoint3 fLightPos;
Jim Van Verth2aa535e2017-02-06 14:36:01 -050036 SkScalar fZDelta;
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050037 SkScalar fAnimTranslate;
Jim Van Verthda965502017-04-11 15:29:14 -040038 SkScalar fAnimAngle;
jvanverthe1a3bc62016-08-12 10:40:38 -070039
40 bool fShowAmbient;
41 bool fShowSpot;
jvanverthd7315f912016-08-17 10:06:18 -070042 bool fUseAlt;
jvanverthe1a3bc62016-08-12 10:40:38 -070043 bool fShowObject;
Robert Phillips95304e32016-10-07 14:44:07 -040044 bool fIgnoreShadowAlpha;
jvanverthe1a3bc62016-08-12 10:40:38 -070045
46public:
Jim Van Verth2aa535e2017-02-06 14:36:01 -050047 ShadowsView()
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050048 : fZDelta(0)
49 , fAnimTranslate(0)
Jim Van Verthda965502017-04-11 15:29:14 -040050 , fAnimAngle(0)
Jim Van Verth2aa535e2017-02-06 14:36:01 -050051 , fShowAmbient(true)
jvanverthe1a3bc62016-08-12 10:40:38 -070052 , fShowSpot(true)
Jim Van Verthb6069df2017-04-28 11:00:35 -040053 , fUseAlt(false)
Robert Phillips95304e32016-10-07 14:44:07 -040054 , fShowObject(true)
55 , fIgnoreShadowAlpha(false) {}
jvanverthe1a3bc62016-08-12 10:40:38 -070056
57protected:
58 void onOnceBeforeDraw() override {
59 fCirclePath.addCircle(0, 0, 50);
60 fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100));
61 fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 100), 4, 4));
Jim Van Verthbce74962017-01-25 09:39:46 -050062 fFunkyRRPath.addRoundRect(SkRect::MakeXYWH(-50, -50, SK_Scalar1 * 100, SK_Scalar1 * 100),
63 40 * SK_Scalar1, 20 * SK_Scalar1,
64 SkPath::kCW_Direction);
65 fCubicPath.cubicTo(100 * SK_Scalar1, 50 * SK_Scalar1,
66 20 * SK_Scalar1, 100 * SK_Scalar1,
67 0 * SK_Scalar1, 0 * SK_Scalar1);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -050068 fSquareRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-50, -50, 100, 100),
69 10, 10));
70 fWideRectPath.addRect(SkRect::MakeXYWH(0, 0, 630, 70));
71 fWideOvalPath.addOval(SkRect::MakeXYWH(0, 0, 630, 70));
Jim Van Verthbce74962017-01-25 09:39:46 -050072
Jim Van Verthb6069df2017-04-28 11:00:35 -040073 fLightPos = SkPoint3::Make(350, 0, 600);
jvanverthe1a3bc62016-08-12 10:40:38 -070074 }
75
76 // overrides from SkEventSink
77 bool onQuery(SkEvent* evt) override {
78 if (SampleCode::TitleQ(*evt)) {
79 SampleCode::TitleR(evt, "AndroidShadows");
80 return true;
81 }
82
83 SkUnichar uni;
84 if (SampleCode::CharQ(*evt, &uni)) {
Jim Van Verth6f449692017-02-14 15:16:46 -050085 bool handled = false;
jvanverthe1a3bc62016-08-12 10:40:38 -070086 switch (uni) {
Jim Van Verth2aa535e2017-02-06 14:36:01 -050087 case 'W':
jvanverthe1a3bc62016-08-12 10:40:38 -070088 fShowAmbient = !fShowAmbient;
Jim Van Verth6f449692017-02-14 15:16:46 -050089 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -070090 break;
91 case 'S':
92 fShowSpot = !fShowSpot;
Jim Van Verth6f449692017-02-14 15:16:46 -050093 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -070094 break;
jvanverthd7315f912016-08-17 10:06:18 -070095 case 'T':
96 fUseAlt = !fUseAlt;
Jim Van Verth6f449692017-02-14 15:16:46 -050097 handled = true;
jvanverthd7315f912016-08-17 10:06:18 -070098 break;
jvanverthe1a3bc62016-08-12 10:40:38 -070099 case 'O':
100 fShowObject = !fShowObject;
Jim Van Verth6f449692017-02-14 15:16:46 -0500101 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700102 break;
103 case '>':
Jim Van Verth2aa535e2017-02-06 14:36:01 -0500104 fZDelta += 0.5f;
Jim Van Verth6f449692017-02-14 15:16:46 -0500105 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700106 break;
107 case '<':
Jim Van Verth2aa535e2017-02-06 14:36:01 -0500108 fZDelta -= 0.5f;
Jim Van Verth6f449692017-02-14 15:16:46 -0500109 handled = true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700110 break;
Robert Phillips95304e32016-10-07 14:44:07 -0400111 case '?':
112 fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
Jim Van Verth6f449692017-02-14 15:16:46 -0500113 handled = true;
Robert Phillips95304e32016-10-07 14:44:07 -0400114 break;
jvanverthe1a3bc62016-08-12 10:40:38 -0700115 default:
116 break;
117 }
Jim Van Verth6f449692017-02-14 15:16:46 -0500118 if (handled) {
119 this->inval(nullptr);
120 return true;
121 }
jvanverthe1a3bc62016-08-12 10:40:38 -0700122 }
123 return this->INHERITED::onQuery(evt);
124 }
125
126 void drawBG(SkCanvas* canvas) {
127 canvas->drawColor(0xFFDDDDDD);
128 }
129
Jim Van Verthda965502017-04-11 15:29:14 -0400130 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
131 std::function<SkScalar(SkScalar, SkScalar)> zFunc,
jvanverthd7315f912016-08-17 10:06:18 -0700132 const SkPaint& paint, SkScalar ambientAlpha,
133 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
Jim Van Verthe7705782017-05-04 14:00:59 -0400134 if (fIgnoreShadowAlpha) {
135 ambientAlpha = 255;
136 spotAlpha = 255;
137 }
Jim Van Verth060d9822017-05-04 09:58:17 -0400138 if (!fShowAmbient) {
139 ambientAlpha = 0;
140 }
141 if (!fShowSpot) {
142 spotAlpha = 0;
143 }
144 uint32_t flags = 0;
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400145 if (fUseAlt) {
Jim Van Verth060d9822017-05-04 09:58:17 -0400146 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400147 }
Jim Van Verth060d9822017-05-04 09:58:17 -0400148 //SkShadowUtils::DrawShadow(canvas, path,
149 // zValue,
150 // lightPos, lightWidth,
151 // ambientAlpha, spotAlpha, SK_ColorBLACK, flags);
152 SkShadowUtils::DrawUncachedShadow(canvas, path, zFunc,
153 lightPos, lightWidth,
154 ambientAlpha, spotAlpha, SK_ColorBLACK, flags);
Jim Van Verth3c1b7db2016-10-31 16:06:51 -0400155
jvanverthe1a3bc62016-08-12 10:40:38 -0700156 if (fShowObject) {
157 canvas->drawPath(path, paint);
Robert Phillips95304e32016-10-07 14:44:07 -0400158 } else {
159 SkPaint strokePaint;
160
161 strokePaint.setColor(paint.getColor());
162 strokePaint.setStyle(SkPaint::kStroke_Style);
163
164 canvas->drawPath(path, strokePaint);
jvanverthe1a3bc62016-08-12 10:40:38 -0700165 }
166 }
167
168 void onDrawContent(SkCanvas* canvas) override {
169 this->drawBG(canvas);
Jim Van Verthb6069df2017-04-28 11:00:35 -0400170 const SkScalar kLightWidth = 800;
171 const SkScalar kAmbientAlpha = 0.1f;
jvanverthd7315f912016-08-17 10:06:18 -0700172 const SkScalar kSpotAlpha = 0.25f;
jvanverthe1a3bc62016-08-12 10:40:38 -0700173
174 SkPaint paint;
175 paint.setAntiAlias(true);
176
jvanverthd7315f912016-08-17 10:06:18 -0700177 SkPoint3 lightPos = fLightPos;
178
jvanverthe1a3bc62016-08-12 10:40:38 -0700179 paint.setColor(SK_ColorWHITE);
180 canvas->translate(200, 90);
Jim Van Verthda965502017-04-11 15:29:14 -0400181 SkScalar zValue = SkTMax(1.0f, 2 + fZDelta);
Jim Van Verthb6069df2017-04-28 11:00:35 -0400182 std::function<SkScalar(SkScalar, SkScalar)> zFunc =
Jim Van Verthda965502017-04-11 15:29:14 -0400183 [zValue](SkScalar, SkScalar) { return zValue; };
184 this->drawShadowedPath(canvas, fRRPath, zFunc, paint, kAmbientAlpha,
jvanverthd7315f912016-08-17 10:06:18 -0700185 lightPos, kLightWidth, kSpotAlpha);
jvanverthe1a3bc62016-08-12 10:40:38 -0700186
187 paint.setColor(SK_ColorRED);
188 canvas->translate(250, 0);
Jim Van Verthb6069df2017-04-28 11:00:35 -0400189 zValue = SkTMax(1.0f, 8 + fZDelta);
Jim Van Verthda965502017-04-11 15:29:14 -0400190 zFunc = [zValue](SkScalar, SkScalar) { return zValue; };
191 this->drawShadowedPath(canvas, fRectPath, zFunc, paint, kAmbientAlpha,
jvanverthd7315f912016-08-17 10:06:18 -0700192 lightPos, kLightWidth, kSpotAlpha);
jvanverthe1a3bc62016-08-12 10:40:38 -0700193
194 paint.setColor(SK_ColorBLUE);
195 canvas->translate(-250, 110);
Jim Van Verth8f7dc9f2017-04-20 15:48:37 -0400196 zValue = SkTMax(1.0f, 12 + fZDelta);
Jim Van Verthda965502017-04-11 15:29:14 -0400197 zFunc = [zValue](SkScalar, SkScalar) { return zValue; };
198 this->drawShadowedPath(canvas, fCirclePath, zFunc, paint, kAmbientAlpha,
jvanverthd7315f912016-08-17 10:06:18 -0700199 lightPos, kLightWidth, 0.5f);
jvanverth6c177a12016-08-17 07:59:41 -0700200
201 paint.setColor(SK_ColorGREEN);
202 canvas->translate(250, 0);
Jim Van Verthda965502017-04-11 15:29:14 -0400203 zValue = SkTMax(1.0f, 64 + fZDelta);
204 zFunc = [zValue](SkScalar, SkScalar) { return zValue; };
205 this->drawShadowedPath(canvas, fRRPath, zFunc, paint, kAmbientAlpha,
jvanverthd7315f912016-08-17 10:06:18 -0700206 lightPos, kLightWidth, kSpotAlpha);
Jim Van Verthbce74962017-01-25 09:39:46 -0500207
208 paint.setColor(SK_ColorYELLOW);
209 canvas->translate(-250, 110);
Jim Van Verthda965502017-04-11 15:29:14 -0400210 zValue = SkTMax(1.0f, 8 + fZDelta);
211 zFunc = [zValue](SkScalar, SkScalar) { return zValue; };
212 this->drawShadowedPath(canvas, fFunkyRRPath, zFunc, paint, kAmbientAlpha,
Jim Van Verthbce74962017-01-25 09:39:46 -0500213 lightPos, kLightWidth, kSpotAlpha);
214
215 paint.setColor(SK_ColorCYAN);
216 canvas->translate(250, 0);
Jim Van Verthda965502017-04-11 15:29:14 -0400217 zValue = SkTMax(1.0f, 16 + fZDelta);
218 zFunc = [zValue](SkScalar, SkScalar) { return zValue; };
219 this->drawShadowedPath(canvas, fCubicPath, zFunc, paint,
Brian Salomonab664fa2017-03-24 16:07:20 +0000220 kAmbientAlpha, lightPos, kLightWidth, kSpotAlpha);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500221
222 // circular reveal
223 SkPath tmpPath;
224 SkPath tmpClipPath;
225 tmpClipPath.addCircle(fAnimTranslate, 0, 60);
226 Op(fSquareRRectPath, tmpClipPath, kIntersect_SkPathOp, &tmpPath);
227
228 paint.setColor(SK_ColorMAGENTA);
229 canvas->translate(-125, 60);
Jim Van Verthda965502017-04-11 15:29:14 -0400230 zValue = SkTMax(1.0f, 32 + fZDelta);
231 zFunc = [zValue](SkScalar, SkScalar) { return zValue; };
232 this->drawShadowedPath(canvas, tmpPath, zFunc, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500233 lightPos, kLightWidth, .5f);
234
235 // perspective paths
236 SkPoint pivot = SkPoint::Make(fWideRectPath.getBounds().width()/2,
237 fWideRectPath.getBounds().height()/2);
Jim Van Verthda965502017-04-11 15:29:14 -0400238 SkPoint translate = SkPoint::Make(100, 450);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500239 paint.setColor(SK_ColorWHITE);
240 Sk3DView view;
241 view.save();
Jim Van Verthda965502017-04-11 15:29:14 -0400242 view.rotateX(fAnimAngle);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500243 SkMatrix persp;
244 view.getMatrix(&persp);
245 persp.preTranslate(-pivot.fX, -pivot.fY);
246 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
247 canvas->setMatrix(persp);
Jim Van Verthda965502017-04-11 15:29:14 -0400248 zValue = SkTMax(1.0f, 16 + fZDelta);
249 SkScalar radians = SkDegreesToRadians(fAnimAngle);
250 zFunc = [zValue, pivot, radians](SkScalar x, SkScalar y) {
251 return SkScalarSin(-radians)*y +
252 zValue - SkScalarSin(-radians)*pivot.fY;
253 };
254 this->drawShadowedPath(canvas, fWideRectPath, zFunc, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500255 lightPos, kLightWidth, .5f);
256
257 pivot = SkPoint::Make(fWideOvalPath.getBounds().width() / 2,
258 fWideOvalPath.getBounds().height() / 2);
Jim Van Verthda965502017-04-11 15:29:14 -0400259 translate = SkPoint::Make(100, 600);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500260 view.restore();
Jim Van Verthda965502017-04-11 15:29:14 -0400261 view.rotateY(fAnimAngle);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500262 view.getMatrix(&persp);
263 persp.preTranslate(-pivot.fX, -pivot.fY);
264 persp.postTranslate(pivot.fX + translate.fX, pivot.fY + translate.fY);
265 canvas->setMatrix(persp);
Jim Van Verthda965502017-04-11 15:29:14 -0400266 zValue = SkTMax(1.0f, 32 + fZDelta);
267 zFunc = [zValue, pivot, radians](SkScalar x, SkScalar y) {
268 return -SkScalarSin(radians)*x +
269 zValue + SkScalarSin(radians)*pivot.fX;
270 };
271 this->drawShadowedPath(canvas, fWideOvalPath, zFunc, paint, .1f,
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500272 lightPos, kLightWidth, .5f);
273 }
274
275 bool onAnimate(const SkAnimTimer& timer) override {
Brian Salomonab664fa2017-03-24 16:07:20 +0000276 fAnimTranslate = timer.pingPong(30, 0, 200, -200);
Jim Van Verthda965502017-04-11 15:29:14 -0400277 fAnimAngle = timer.pingPong(15, 0, 0, 20);
Jim Van Verth2c1cd6d2017-03-10 14:34:51 -0500278
279 return true;
jvanverthe1a3bc62016-08-12 10:40:38 -0700280 }
281
jvanverthe1a3bc62016-08-12 10:40:38 -0700282private:
Jim Van Verth6f449692017-02-14 15:16:46 -0500283 typedef SampleView INHERITED;
jvanverthe1a3bc62016-08-12 10:40:38 -0700284};
285
286//////////////////////////////////////////////////////////////////////////////
287
288static SkView* MyFactory() { return new ShadowsView; }
289static SkViewRegister reg(MyFactory);