1
2/*
3 * Copyright 2020 Google LLC
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 "include/core/SkCanvas.h"
9#include "include/core/SkColorFilter.h"
10#include "include/core/SkPath.h"
11#include "include/core/SkPoint3.h"
12#include "include/pathops/SkPathOps.h"
13#include "include/utils/SkCamera.h"
14#include "include/utils/SkShadowUtils.h"
15#include "samplecode/Sample.h"
16#include "src/core/SkBlurMask.h"
17#include "src/utils/SkUTF.h"
18#include "tools/ToolUtils.h"
19#include "tools/timer/TimeUtils.h"
20
21////////////////////////////////////////////////////////////////////////////
22
23class MaterialShadowsView : public Sample {
24    SkPath    fCirclePath;
25    SkPath    fCapsulePath;
26    SkPath    fLargeRRPath;
27    SkPath    fSmallRRPath;
28
29    SkPoint3  fLightPos;
30
31    void onOnceBeforeDraw() override {
32        fCirclePath.addCircle(0, 0, 56/2);
33        fCapsulePath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-64, -24, 128, 48), 24, 24));
34        fLargeRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-64, -64, 128, 128), 4, 4));
35        fSmallRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-40, -40, 80, 80), 4, 4));
36
37        fLightPos = SkPoint3::Make(0, -700, 700);
38    }
39
40    SkString name() override { return SkString("MaterialShadows"); }
41
42    void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
43                          const SkPoint3& zPlaneParams,
44                          const SkPaint& paint, SkScalar ambientAlpha,
45                          const SkPoint3& lightPos, SkScalar lightRadius, SkScalar spotAlpha) {
46        uint32_t flags = 0;
47        flags |= SkShadowFlags::kDirectionalLight_ShadowFlag;
48
49        SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
50        SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
51        SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, lightPos, lightRadius,
52                                  ambientColor, spotColor, flags);
53
54        canvas->drawPath(path, paint);
55    }
56
57    void onDrawContent(SkCanvas* canvas) override {
58        canvas->drawColor(0xFFFFFFFF);
59
60        const SkScalar kLightRadius = 1.1f;
61        const SkScalar kAmbientAlpha = 0.05f;
62        const SkScalar kSpotAlpha = 0.35f;
63
64        const SkScalar elevations[] = { 1, 3, 6, 8, 12, 24 };
65
66        SkPaint paint;
67        paint.setAntiAlias(true);
68
69        SkPoint3 lightPos = fLightPos;
70        SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, 0);
71
72        paint.setColor(SK_ColorWHITE);
73        canvas->save();
74        canvas->translate(80, 80);
75        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
76            zPlaneParams.fZ = elevations[i];
77            this->drawShadowedPath(canvas, fCirclePath, zPlaneParams, paint, kAmbientAlpha,
78                                   lightPos, kLightRadius, kSpotAlpha);
79            canvas->translate(80, 0);
80        }
81        canvas->restore();
82
83        canvas->save();
84        canvas->translate(120, 175);
85        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
86            zPlaneParams.fZ = elevations[i];
87            this->drawShadowedPath(canvas, fCapsulePath, zPlaneParams, paint, kAmbientAlpha,
88                                   lightPos, kLightRadius, kSpotAlpha);
89            canvas->translate(160, 0);
90        }
91        canvas->restore();
92
93        canvas->save();
94        canvas->translate(120, 320);
95        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
96            zPlaneParams.fZ = elevations[i];
97            this->drawShadowedPath(canvas, fLargeRRPath, zPlaneParams, paint, kAmbientAlpha,
98                                   lightPos, kLightRadius, kSpotAlpha);
99            canvas->translate(160, 0);
100        }
101        canvas->restore();
102
103        canvas->save();
104        canvas->translate(100, 475);
105        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
106            zPlaneParams.fZ = elevations[i];
107            this->drawShadowedPath(canvas, fSmallRRPath, zPlaneParams, paint, kAmbientAlpha,
108                                   lightPos, kLightRadius, kSpotAlpha);
109            canvas->translate(160, 0);
110        }
111        canvas->restore();
112
113        canvas->save();
114        canvas->translate(100, 600);
115        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
116            canvas->save();
117            zPlaneParams.fZ = elevations[i];
118            canvas->rotate(10);
119            this->drawShadowedPath(canvas, fSmallRRPath, zPlaneParams, paint, kAmbientAlpha,
120                                   lightPos, kLightRadius, kSpotAlpha);
121            canvas->restore();
122            canvas->translate(160, 0);
123        }
124        canvas->restore();
125
126        canvas->save();
127        canvas->translate(100, 725);
128        for (unsigned int i = 0; i < SK_ARRAY_COUNT(elevations); ++i) {
129            canvas->save();
130            zPlaneParams.fZ = elevations[i];
131            canvas->rotate(45);
132            this->drawShadowedPath(canvas, fSmallRRPath, zPlaneParams, paint, kAmbientAlpha,
133                                   lightPos, kLightRadius, kSpotAlpha);
134            canvas->restore();
135            canvas->translate(160, 0);
136        }
137        canvas->restore();
138
139    }
140
141private:
142    using INHERITED = Sample;
143};
144
145//////////////////////////////////////////////////////////////////////////////
146
147DEF_SAMPLE( return new MaterialShadowsView(); )
148