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 "SampleCode.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 SampleView {
33 public:
34     SkBitmap        fDiffuseBitmap;
35     SkBitmap        fNormalBitmap;
36     SkScalar        fLightAngle;
37     SkScalar        fColorFactor;
38 
LightingView()39     LightingView() {
40         SkString diffusePath = GetResourcePath("brickwork-texture.jpg");
41         decode_file(diffusePath.c_str(), &fDiffuseBitmap);
42         SkString normalPath = GetResourcePath("brickwork_normal-map.jpg");
43         decode_file(normalPath.c_str(), &fNormalBitmap);
44 
45         fLightAngle = 0.0f;
46         fColorFactor = 0.0f;
47     }
48 
49 protected:
50     // overrides from SkEventSink
onQuery(SkEvent * evt)51     bool onQuery(SkEvent* evt) override {
52         if (SampleCode::TitleQ(*evt)) {
53             SampleCode::TitleR(evt, "Lighting");
54             return true;
55         }
56         return this->INHERITED::onQuery(evt);
57     }
58 
onDrawContent(SkCanvas * canvas)59     void onDrawContent(SkCanvas* canvas) override {
60         fLightAngle += 0.015f;
61         fColorFactor += 0.01f;
62         if (fColorFactor > 1.0f) {
63             fColorFactor = 0.0f;
64         }
65 
66         sk_sp<SkLights> lights(create_lights(fLightAngle, fColorFactor));
67         SkPaint paint;
68         sk_sp<SkShader> normalMap = SkShader::MakeBitmapShader(fNormalBitmap,
69             SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, nullptr);
70         sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(
71                 std::move(normalMap), SkMatrix::I());
72         sk_sp<SkShader> diffuseShader = SkShader::MakeBitmapShader(fDiffuseBitmap,
73                 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, nullptr);
74         paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::move(normalSource),
75                                                std::move(lights)));
76         paint.setColor(SK_ColorBLACK);
77 
78         SkRect r = SkRect::MakeWH((SkScalar)fDiffuseBitmap.width(),
79                                   (SkScalar)fDiffuseBitmap.height());
80         canvas->drawRect(r, paint);
81 
82         // so we're constantly updating
83         this->inval(nullptr);
84     }
85 
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)86     SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
87         this->inval(nullptr);
88         return this->INHERITED::onFindClickHandler(x, y, modi);
89     }
90 
91 private:
92     typedef SampleView INHERITED;
93 };
94 
95 //////////////////////////////////////////////////////////////////////////////
96 
MyFactory()97 static SkView* MyFactory() { return new LightingView; }
98 static SkViewRegister reg(MyFactory);
99