1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
9#include "gm.h"
10#include "sk_tool_utils.h"
11#include "SkPathEffect.h"
12#include "SkPictureRecorder.h"
13#include "SkShadowPaintFilterCanvas.h"
14#include "SkShadowShader.h"
15#include "SkSurface.h"
16
17#ifdef SK_EXPERIMENTAL_SHADOWING
18
19
20static sk_sp<SkPicture> make_test_picture(int width, int height) {
21    SkPictureRecorder recorder;
22
23    // LONG RANGE TODO: eventually add SkBBHFactory (bounding box factory)
24    SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(width, height));
25
26    SkASSERT(canvas->getTotalMatrix().isIdentity());
27    SkPaint paint;
28    paint.setColor(SK_ColorGRAY);
29
30    // LONG RANGE TODO: tag occluders
31    // LONG RANGE TODO: track number of IDs we need (hopefully less than 256)
32    //                  and determinate the mapping from z to id
33
34    // universal receiver, "ground"
35    canvas->drawRect(SkRect::MakeIWH(width, height), paint);
36
37    // TODO: Maybe add the ID here along with the depth
38
39    paint.setColor(0xFFEE8888);
40
41    canvas->translateZ(80);
42    canvas->drawRect(SkRect::MakeLTRB(200,150,350,300), paint);
43
44    paint.setColor(0xFF88EE88);
45
46    canvas->translateZ(80);
47    canvas->drawRect(SkRect::MakeLTRB(150,200,300,350), paint);
48
49    paint.setColor(0xFF8888EE);
50
51    canvas->translateZ(80);
52    canvas->drawRect(SkRect::MakeLTRB(100,100,250,250), paint);
53    // TODO: Add an assert that Z order matches painter's order
54    // TODO: think about if the Z-order always matching painting order is too strict
55
56    return recorder.finishRecordingAsPicture();
57}
58
59namespace skiagm {
60
61class ShadowMapsGM : public GM {
62public:
63    ShadowMapsGM() {
64        this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
65    }
66
67    void onOnceBeforeDraw() override {
68        // Create a light set consisting of
69        //   - bluish directional light pointing more right than down
70        //   - reddish directional light pointing more down than right
71        //   - soft white ambient light
72
73        SkLights::Builder builder;
74        builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.2f, 0.3f, 0.4f),
75                                                     SkVector3::Make(0.2f, 0.1f, 1.0f)));
76        builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.4f, 0.3f, 0.2f),
77                                                     SkVector3::Make(0.1f, 0.2f, 1.0f)));
78        builder.setAmbientLightColor(SkColor3f::Make(0.4f, 0.4f, 0.4f));
79        fLights = builder.finish();
80
81        fShadowParams.fShadowRadius = 4.0f;
82        fShadowParams.fBiasingConstant = 0.3f;
83        fShadowParams.fMinVariance = 1024;
84        fShadowParams.fType = SkShadowParams::kVariance_ShadowType;
85    }
86
87protected:
88    static constexpr int kWidth = 400;
89    static constexpr int kHeight = 400;
90
91    SkString onShortName() override {
92        return SkString("shadowmaps");
93    }
94
95    SkISize onISize() override {
96        return SkISize::Make(kWidth, kHeight);
97    }
98
99    void onDraw(SkCanvas* canvas) override {
100        // This picture stores the picture of the scene.
101        // It's used to generate the depth maps.
102        sk_sp<SkPicture> pic(make_test_picture(kWidth, kHeight));
103        canvas->setLights(fLights);
104        canvas->drawShadowedPicture(pic, nullptr, nullptr, fShadowParams);
105    }
106
107private:
108    sk_sp<SkLights> fLights;
109    SkShadowParams fShadowParams;
110    typedef GM INHERITED;
111};
112
113//////////////////////////////////////////////////////////////////////////////
114
115DEF_GM(return new ShadowMapsGM;)
116}
117
118#endif
119