Add fixes & test for isConfigTexturable and isConfigRenderable
[platform/upstream/libSkiaSharp.git] / gm / lightingshader.cpp
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 "gm.h"
9 #include "sk_tool_utils.h"
10 #include "SkLightingShader.h"
11 #include "SkNormalSource.h"
12 #include "SkPoint3.h"
13 #include "SkShader.h"
14
15 // Create a hemispherical normal map
16 static SkBitmap make_hemi_normalmap(int texSize) {
17     SkBitmap hemi;
18     hemi.allocN32Pixels(texSize, texSize);
19
20     sk_tool_utils::create_hemi_normal_map(&hemi, SkIRect::MakeWH(texSize, texSize));
21     return hemi;
22 }
23
24 // Create a truncated pyramid normal map
25 static SkBitmap make_frustum_normalmap(int texSize) {
26     SkBitmap frustum;
27     frustum.allocN32Pixels(texSize, texSize);
28
29     sk_tool_utils::create_frustum_normal_map(&frustum, SkIRect::MakeWH(texSize, texSize));
30     return frustum;
31 }
32
33 // Create a tetrahedral normal map
34 static SkBitmap make_tetra_normalmap(int texSize) {
35     SkBitmap tetra;
36     tetra.allocN32Pixels(texSize, texSize);
37
38     sk_tool_utils::create_tetra_normal_map(&tetra, SkIRect::MakeWH(texSize, texSize));
39     return tetra;
40 }
41
42 namespace skiagm {
43
44 // This GM exercises lighting shaders.
45 class LightingShaderGM : public GM {
46 public:
47     LightingShaderGM() {
48         this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
49
50         SkLights::Builder builder;
51
52         builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
53                                                      SkVector3::Make(SK_ScalarRoot2Over2,
54                                                                      0.0f,
55                                                                      SK_ScalarRoot2Over2)));
56         builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f));
57
58         fLights = builder.finish();
59     }
60
61 protected:
62     enum NormalMap {
63         kHemi_NormalMap,
64         kFrustum_NormalMap,
65         kTetra_NormalMap,
66
67         kLast_NormalMap = kTetra_NormalMap
68     };
69
70     static constexpr int kNormalMapCount = kLast_NormalMap+1;
71
72     SkString onShortName() override {
73         return SkString("lightingshader");
74     }
75
76     SkISize onISize() override {
77         return SkISize::Make(kGMSize, kGMSize);
78     }
79
80     void onOnceBeforeDraw() override {
81         fDiffuse = sk_tool_utils::create_checkerboard_bitmap(
82                                                         kTexSize, kTexSize,
83                                                         sk_tool_utils::color_to_565(0x0),
84                                                         sk_tool_utils::color_to_565(0xFF804020),
85                                                         8);
86
87         fNormalMaps[kHemi_NormalMap]    = make_hemi_normalmap(kTexSize);
88         fNormalMaps[kFrustum_NormalMap] = make_frustum_normalmap(kTexSize);
89         fNormalMaps[kTetra_NormalMap]   = make_tetra_normalmap(kTexSize);
90     }
91
92     void drawRect(SkCanvas* canvas, const SkRect& r, NormalMap mapType) {
93
94         SkRect bitmapBounds = SkRect::MakeIWH(fDiffuse.width(), fDiffuse.height());
95
96         SkMatrix matrix;
97         matrix.setRectToRect(bitmapBounds, r, SkMatrix::kFill_ScaleToFit);
98
99         const SkMatrix& ctm = canvas->getTotalMatrix();
100
101         SkPaint paint;
102         sk_sp<SkShader> diffuseShader = SkShader::MakeBitmapShader(fDiffuse,
103                 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix);
104         sk_sp<SkShader> normalMap = SkShader::MakeBitmapShader(fNormalMaps[mapType],
105                 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix);
106         sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeFromNormalMap(std::move(normalMap),
107                                                                                ctm);
108         paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::move(normalSource),
109                                                fLights));
110
111         canvas->drawRect(r, paint);
112     }
113
114     void onDraw(SkCanvas* canvas) override {
115         SkMatrix m;
116         SkRect r;
117
118         {
119             r = SkRect::MakeWH(SkIntToScalar(kTexSize), SkIntToScalar(kTexSize));
120             this->drawRect(canvas, r, kHemi_NormalMap);
121
122             canvas->save();
123             m.setRotate(45.0f, r.centerX(), r.centerY());
124             m.postTranslate(kGMSize/2.0f - kTexSize/2.0f, 0.0f);
125             canvas->setMatrix(m);
126             this->drawRect(canvas, r, kHemi_NormalMap);
127             canvas->restore();
128         }
129
130         {
131             r.offset(kGMSize - kTexSize, 0);
132             this->drawRect(canvas, r, kFrustum_NormalMap);
133
134             canvas->save();
135             m.setRotate(45.0f, r.centerX(), r.centerY());
136             m.postTranslate(0.0f, kGMSize/2.0f - kTexSize/2.0f);
137             canvas->setMatrix(m);
138             this->drawRect(canvas, r, kFrustum_NormalMap);
139             canvas->restore();
140         }
141
142         {
143             r.offset(0, kGMSize - kTexSize);
144             this->drawRect(canvas, r, kTetra_NormalMap);
145
146             canvas->save();
147             m.setRotate(45.0f, r.centerX(), r.centerY());
148             m.postTranslate(-kGMSize/2.0f + kTexSize/2.0f, 0.0f);
149             canvas->setMatrix(m);
150             this->drawRect(canvas, r, kTetra_NormalMap);
151             canvas->restore();
152         }
153
154         {
155             r.offset(kTexSize - kGMSize, 0);
156             this->drawRect(canvas, r, kHemi_NormalMap);
157
158             canvas->save();
159             m.setRotate(45.0f, r.centerX(), r.centerY());
160             m.postTranslate(0.0f, -kGMSize/2.0f + kTexSize/2.0f);
161             canvas->setMatrix(m);
162             this->drawRect(canvas, r, kHemi_NormalMap);
163             canvas->restore();
164         }
165     }
166
167 private:
168     static constexpr int kTexSize = 128;
169     static constexpr int kGMSize  = 512;
170
171     SkBitmap        fDiffuse;
172     SkBitmap        fNormalMaps[kNormalMapCount];
173
174     sk_sp<SkLights> fLights;
175
176     typedef GM INHERITED;
177 };
178
179 //////////////////////////////////////////////////////////////////////////////
180
181 DEF_GM(return new LightingShaderGM;)
182 }