2 * Copyright 2015 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
9 #include "sk_tool_utils.h"
10 #include "SkLightingShader.h"
11 #include "SkNormalSource.h"
15 // Create a hemispherical normal map
16 static SkBitmap make_hemi_normalmap(int texSize) {
18 hemi.allocN32Pixels(texSize, texSize);
20 sk_tool_utils::create_hemi_normal_map(&hemi, SkIRect::MakeWH(texSize, texSize));
24 // Create a truncated pyramid normal map
25 static SkBitmap make_frustum_normalmap(int texSize) {
27 frustum.allocN32Pixels(texSize, texSize);
29 sk_tool_utils::create_frustum_normal_map(&frustum, SkIRect::MakeWH(texSize, texSize));
33 // Create a tetrahedral normal map
34 static SkBitmap make_tetra_normalmap(int texSize) {
36 tetra.allocN32Pixels(texSize, texSize);
38 sk_tool_utils::create_tetra_normal_map(&tetra, SkIRect::MakeWH(texSize, texSize));
44 // This GM exercises lighting shaders.
45 class LightingShaderGM : public GM {
48 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
50 SkLights::Builder builder;
52 builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
53 SkVector3::Make(SK_ScalarRoot2Over2,
55 SK_ScalarRoot2Over2)));
56 builder.setAmbientLightColor(SkColor3f::Make(0.2f, 0.2f, 0.2f));
58 fLights = builder.finish();
67 kLast_NormalMap = kTetra_NormalMap
70 static constexpr int kNormalMapCount = kLast_NormalMap+1;
72 SkString onShortName() override {
73 return SkString("lightingshader");
76 SkISize onISize() override {
77 return SkISize::Make(kGMSize, kGMSize);
80 void onOnceBeforeDraw() override {
81 fDiffuse = sk_tool_utils::create_checkerboard_bitmap(
83 sk_tool_utils::color_to_565(0x0),
84 sk_tool_utils::color_to_565(0xFF804020),
87 fNormalMaps[kHemi_NormalMap] = make_hemi_normalmap(kTexSize);
88 fNormalMaps[kFrustum_NormalMap] = make_frustum_normalmap(kTexSize);
89 fNormalMaps[kTetra_NormalMap] = make_tetra_normalmap(kTexSize);
92 void drawRect(SkCanvas* canvas, const SkRect& r, NormalMap mapType) {
94 SkRect bitmapBounds = SkRect::MakeIWH(fDiffuse.width(), fDiffuse.height());
97 matrix.setRectToRect(bitmapBounds, r, SkMatrix::kFill_ScaleToFit);
99 const SkMatrix& ctm = canvas->getTotalMatrix();
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),
108 paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::move(normalSource),
111 canvas->drawRect(r, paint);
114 void onDraw(SkCanvas* canvas) override {
119 r = SkRect::MakeWH(SkIntToScalar(kTexSize), SkIntToScalar(kTexSize));
120 this->drawRect(canvas, r, kHemi_NormalMap);
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);
131 r.offset(kGMSize - kTexSize, 0);
132 this->drawRect(canvas, r, kFrustum_NormalMap);
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);
143 r.offset(0, kGMSize - kTexSize);
144 this->drawRect(canvas, r, kTetra_NormalMap);
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);
155 r.offset(kTexSize - kGMSize, 0);
156 this->drawRect(canvas, r, kHemi_NormalMap);
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);
168 static constexpr int kTexSize = 128;
169 static constexpr int kGMSize = 512;
172 SkBitmap fNormalMaps[kNormalMapCount];
174 sk_sp<SkLights> fLights;
176 typedef GM INHERITED;
179 //////////////////////////////////////////////////////////////////////////////
181 DEF_GM(return new LightingShaderGM;)