blob: 7e33504477fef81e0c5740caf505e1bdb89dc91c [file] [log] [blame]
robertphillips5f865b92015-07-29 12:28:04 -07001/*
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
robertphillips5f865b92015-07-29 12:28:04 -070010#include "SkLightingShader.h"
robertphillipsea4529d2015-08-17 15:04:47 -070011#include "SkPoint3.h"
12#include "SkShader.h"
robertphillips5f865b92015-07-29 12:28:04 -070013
14static SkBitmap make_checkerboard(int texSize) {
15 SkBitmap bitmap;
16 bitmap.allocN32Pixels(texSize, texSize);
17
18 SkCanvas canvas(bitmap);
19 sk_tool_utils::draw_checkerboard(&canvas,
20 sk_tool_utils::color_to_565(0x0),
21 sk_tool_utils::color_to_565(0xFF804020),
robertphillips640898f2015-07-30 05:09:17 -070022 2);
robertphillips5f865b92015-07-29 12:28:04 -070023 return bitmap;
24}
25
26// Create a hemispherical normal map
robertphillips640898f2015-07-30 05:09:17 -070027static SkBitmap make_hemi_normalmap(int texSize) {
robertphillips5f865b92015-07-29 12:28:04 -070028 SkBitmap hemi;
29 hemi.allocN32Pixels(texSize, texSize);
30
robertphillipsea4529d2015-08-17 15:04:47 -070031 sk_tool_utils::create_hemi_normal_map(&hemi, SkIRect::MakeWH(texSize, texSize));
robertphillips5f865b92015-07-29 12:28:04 -070032 return hemi;
33}
34
robertphillips640898f2015-07-30 05:09:17 -070035// Create a truncated pyramid normal map
36static SkBitmap make_frustum_normalmap(int texSize) {
37 SkBitmap frustum;
38 frustum.allocN32Pixels(texSize, texSize);
39
robertphillipsea4529d2015-08-17 15:04:47 -070040 sk_tool_utils::create_frustum_normal_map(&frustum, SkIRect::MakeWH(texSize, texSize));
robertphillips640898f2015-07-30 05:09:17 -070041 return frustum;
42}
robertphillips5f865b92015-07-29 12:28:04 -070043
robertphillipsea4529d2015-08-17 15:04:47 -070044// Create a tetrahedral normal map
45static SkBitmap make_tetra_normalmap(int texSize) {
46 SkBitmap tetra;
47 tetra.allocN32Pixels(texSize, texSize);
48
49 sk_tool_utils::create_tetra_normal_map(&tetra, SkIRect::MakeWH(texSize, texSize));
50 return tetra;
51}
52
robertphillips5f865b92015-07-29 12:28:04 -070053namespace skiagm {
54
55// This GM exercises lighting shaders.
56class LightingShaderGM : public GM {
57public:
58 LightingShaderGM() {
59 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
robertphillips640898f2015-07-30 05:09:17 -070060
robertphillipsa9652ac2015-07-31 05:17:24 -070061 fLight.fColor = SkColor3f::Make(1.0f, 1.0f, 1.0f);
robertphillipsea4529d2015-08-17 15:04:47 -070062 fLight.fDirection = SkVector3::Make(0.0f, 0.0f, 1.0f);
robertphillips640898f2015-07-30 05:09:17 -070063
robertphillipsa9652ac2015-07-31 05:17:24 -070064 fAmbient = SkColor3f::Make(0.1f, 0.1f, 0.1f);
robertphillips5f865b92015-07-29 12:28:04 -070065 }
66
67protected:
robertphillipsea4529d2015-08-17 15:04:47 -070068 enum NormalMap {
69 kHemi_NormalMap,
70 kFrustum_NormalMap,
71 kTetra_NormalMap,
72
73 kLast_NormalMap = kTetra_NormalMap
74 };
75
76 static const int kNormalMapCount = kLast_NormalMap+1;
robertphillips5f865b92015-07-29 12:28:04 -070077
78 SkString onShortName() override {
79 return SkString("lightingshader");
80 }
81
82 SkISize onISize() override {
robertphillips640898f2015-07-30 05:09:17 -070083 return SkISize::Make(kGMSize, kGMSize);
robertphillips5f865b92015-07-29 12:28:04 -070084 }
85
86 void onOnceBeforeDraw() override {
87 fDiffuse = make_checkerboard(kTexSize);
robertphillipsea4529d2015-08-17 15:04:47 -070088
89 fNormalMaps[kHemi_NormalMap] = make_hemi_normalmap(kTexSize);
90 fNormalMaps[kFrustum_NormalMap] = make_frustum_normalmap(kTexSize);
91 fNormalMaps[kTetra_NormalMap] = make_tetra_normalmap(kTexSize);
robertphillips5f865b92015-07-29 12:28:04 -070092 }
93
robertphillipsea4529d2015-08-17 15:04:47 -070094 void drawRect(SkCanvas* canvas, const SkRect& r, NormalMap mapType) {
robertphillips5f865b92015-07-29 12:28:04 -070095
robertphillips640898f2015-07-30 05:09:17 -070096 SkRect bitmapBounds = SkRect::MakeIWH(fDiffuse.width(), fDiffuse.height());
robertphillips5f865b92015-07-29 12:28:04 -070097
robertphillips640898f2015-07-30 05:09:17 -070098 SkMatrix matrix;
99 matrix.setRectToRect(bitmapBounds, r, SkMatrix::kFill_ScaleToFit);
100
101 SkAutoTUnref<SkShader> fShader(SkLightingShader::Create(
102 fDiffuse,
robertphillipsea4529d2015-08-17 15:04:47 -0700103 fNormalMaps[mapType],
robertphillips640898f2015-07-30 05:09:17 -0700104 fLight, fAmbient,
105 &matrix));
robertphillips5f865b92015-07-29 12:28:04 -0700106
107 SkPaint paint;
108 paint.setShader(fShader);
109
robertphillips5f865b92015-07-29 12:28:04 -0700110 canvas->drawRect(r, paint);
111 }
112
robertphillips640898f2015-07-30 05:09:17 -0700113 void onDraw(SkCanvas* canvas) override {
114 SkRect r = SkRect::MakeWH(SkIntToScalar(kTexSize), SkIntToScalar(kTexSize));
robertphillipsea4529d2015-08-17 15:04:47 -0700115 this->drawRect(canvas, r, kHemi_NormalMap);
robertphillips640898f2015-07-30 05:09:17 -0700116
117 r.offset(kGMSize - kTexSize, 0);
robertphillipsea4529d2015-08-17 15:04:47 -0700118 this->drawRect(canvas, r, kFrustum_NormalMap);
robertphillips640898f2015-07-30 05:09:17 -0700119
120 r.offset(0, kGMSize - kTexSize);
robertphillipsea4529d2015-08-17 15:04:47 -0700121 this->drawRect(canvas, r, kTetra_NormalMap);
robertphillips640898f2015-07-30 05:09:17 -0700122
123 r.offset(kTexSize - kGMSize, 0);
robertphillipsea4529d2015-08-17 15:04:47 -0700124 this->drawRect(canvas, r, kHemi_NormalMap);
robertphillips640898f2015-07-30 05:09:17 -0700125 }
126
robertphillips5f865b92015-07-29 12:28:04 -0700127private:
128 static const int kTexSize = 128;
robertphillips640898f2015-07-30 05:09:17 -0700129 static const int kGMSize = 512;
robertphillips5f865b92015-07-29 12:28:04 -0700130
robertphillips640898f2015-07-30 05:09:17 -0700131 SkBitmap fDiffuse;
robertphillipsea4529d2015-08-17 15:04:47 -0700132 SkBitmap fNormalMaps[kNormalMapCount];
robertphillips640898f2015-07-30 05:09:17 -0700133
134 SkLightingShader::Light fLight;
robertphillipsa9652ac2015-07-31 05:17:24 -0700135 SkColor3f fAmbient;
robertphillips5f865b92015-07-29 12:28:04 -0700136
137 typedef GM INHERITED;
138};
139
140//////////////////////////////////////////////////////////////////////////////
141
142DEF_GM( return SkNEW(LightingShaderGM); )
143
144}