1 /*
2  * Copyright 2015 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 #include "DecodeFile.h"
9 #include "Sample.h"
10 #include "Resources.h"
11 #include "SkCanvas.h"
12 #include "SkLightingShader.h"
13 #include "SkNormalSource.h"
14 #include "SkPoint3.h"
15 
create_lights(SkScalar angle,SkScalar blue)16 static sk_sp<SkLights> create_lights(SkScalar angle, SkScalar blue) {
17 
18     const SkVector3 dir = SkVector3::Make(SkScalarSin(angle)*SkScalarSin(SK_ScalarPI*0.25f),
19                                           SkScalarCos(angle)*SkScalarSin(SK_ScalarPI*0.25f),
20                                           SkScalarCos(SK_ScalarPI*0.25f));
21 
22     SkLights::Builder builder;
23 
24     builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, blue), dir));
25     builder.setAmbientLightColor(SkColor3f::Make(0.1f, 0.1f, 0.1f));
26 
27     return builder.finish();
28 }
29 
30 ////////////////////////////////////////////////////////////////////////////
31 
32 class LightingView : public Sample {
33 public:
LightingView()34     LightingView() : fLightAngle(0.0f) , fColorFactor(0.0f) {
35         {
36             SkBitmap diffuseBitmap;
37             SkAssertResult(GetResourceAsBitmap("images/brickwork-texture.jpg", &diffuseBitmap));
38 
39             fRect = SkRect::MakeIWH(diffuseBitmap.width(), diffuseBitmap.height());
40 
41             fDiffuseShader = SkShader::MakeBitmapShader(diffuseBitmap,
42                                                         SkShader::kClamp_TileMode,
43                                                         SkShader::kClamp_TileMode,
44                                                         nullptr);
45         }
46 
47         {
48             SkBitmap normalBitmap;
49             SkAssertResult(GetResourceAsBitmap("images/brickwork_normal-map.jpg", &normalBitmap));
50 
51             sk_sp<SkShader> normalMap = SkShader::MakeBitmapShader(normalBitmap,
52                                                                    SkShader::kClamp_TileMode,
53                                                                    SkShader::kClamp_TileMode,
54                                                                    nullptr);
55             fNormalSource = SkNormalSource::MakeFromNormalMap(std::move(normalMap), SkMatrix::I());
56         }
57     }
58 
59 protected:
onQuery(Sample::Event * evt)60     bool onQuery(Sample::Event* evt) override {
61         if (Sample::TitleQ(*evt)) {
62             Sample::TitleR(evt, "Lighting");
63             return true;
64         }
65         return this->INHERITED::onQuery(evt);
66     }
67 
onDrawContent(SkCanvas * canvas)68     void onDrawContent(SkCanvas* canvas) override {
69         sk_sp<SkLights> lights(create_lights(fLightAngle, fColorFactor));
70 
71         SkPaint paint;
72         paint.setShader(SkLightingShader::Make(fDiffuseShader,
73                                                fNormalSource,
74                                                std::move(lights)));
75         paint.setColor(SK_ColorBLACK);
76 
77         canvas->drawRect(fRect, paint);
78     }
79 
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)80     Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
81         return this->INHERITED::onFindClickHandler(x, y, modi);
82     }
83 
onAnimate(const SkAnimTimer & timer)84     bool onAnimate(const SkAnimTimer& timer) override {
85         fLightAngle += 0.015f;
86         fColorFactor += 0.01f;
87         if (fColorFactor > 1.0f) {
88             fColorFactor = 0.0f;
89         }
90 
91         return true;
92     }
93 
94 private:
95     SkRect                fRect;
96     sk_sp<SkShader>       fDiffuseShader;
97     sk_sp<SkNormalSource> fNormalSource;
98 
99     SkScalar              fLightAngle;
100     SkScalar              fColorFactor;
101 
102     typedef Sample INHERITED;
103 };
104 
105 //////////////////////////////////////////////////////////////////////////////
106 
107 DEF_SAMPLE( return new LightingView(); )
108