OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "gm.h" | 8 #include "gm.h" |
9 #include "SkLightingShader.h" | 9 #include "SkLightingShader.h" |
10 #include "SkNormalSource.h" | 10 #include "SkNormalSource.h" |
11 #include "SkPoint3.h" | 11 #include "SkPoint3.h" |
12 #include "SkShader.h" | 12 #include "SkShader.h" |
13 | 13 |
14 // Create a truncated pyramid normal map | 14 // Create a truncated pyramid normal map |
15 static SkBitmap make_frustum_normalmap(int texSize) { | 15 static SkBitmap make_frustum_normalmap(int texSize) { |
16 SkBitmap frustum; | 16 SkBitmap frustum; |
17 frustum.allocN32Pixels(texSize, texSize); | 17 frustum.allocN32Pixels(texSize, texSize); |
18 | 18 |
19 sk_tool_utils::create_frustum_normal_map(&frustum, SkIRect::MakeWH(texSize,
texSize)); | 19 sk_tool_utils::create_frustum_normal_map(&frustum, SkIRect::MakeWH(texSize,
texSize)); |
20 return frustum; | 20 return frustum; |
21 } | 21 } |
22 | 22 |
23 namespace skiagm { | 23 namespace skiagm { |
24 | 24 |
25 // This GM exercises lighting shaders. Specifically, nullptr arguments, scaling
when using | 25 // This GM exercises lighting shaders. Specifically, nullptr arguments, scaling
when using |
26 // normal maps, and paint transparency. | 26 // normal maps, paint transparency, zero directional lights, multiple directiona
l lights. |
27 class LightingShader2GM : public GM { | 27 class LightingShader2GM : public GM { |
28 public: | 28 public: |
29 LightingShader2GM() { | 29 LightingShader2GM() { |
30 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); | 30 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); |
31 } | 31 } |
32 | 32 |
33 protected: | 33 protected: |
34 SkString onShortName() override { | 34 SkString onShortName() override { |
35 return SkString("lightingshader2"); | 35 return SkString("lightingshader2"); |
36 } | 36 } |
37 | 37 |
38 SkISize onISize() override { | 38 SkISize onISize() override { |
39 return SkISize::Make(600, 740); | 39 return SkISize::Make(600, 740); |
40 } | 40 } |
41 | 41 |
42 void onOnceBeforeDraw() override { | 42 void onOnceBeforeDraw() override { |
| 43 const SkVector3 kLightFromUpperRight = SkVector3::Make(0.788f, 0.394f, 0
.473f); |
| 44 const SkVector3 kLightFromUpperLeft = SkVector3::Make(-0.788f, 0.394f, 0
.473f); |
| 45 |
| 46 // Standard set of lights |
43 SkLights::Builder builder; | 47 SkLights::Builder builder; |
44 const SkVector3 kLightFromUpperRight = SkVector3::Make(0.788f, 0.394f, 0
.473f); | |
45 | |
46 builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f,
1.0f), | 48 builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f,
1.0f), |
47 kLightFromUpperRight)); | 49 kLightFromUpperRight)); |
48 builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.2f, 0.2f, 0.2
f))); | 50 builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.2f, 0.2f, 0.2
f))); |
49 fLights = builder.finish(); | 51 fLights = builder.finish(); |
50 | 52 |
| 53 // No directional lights |
| 54 SkLights::Builder builderNoDir; |
| 55 builderNoDir.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.2f, 0.2f
, 0.2f))); |
| 56 fLightsNoDir = builderNoDir.finish(); |
| 57 |
| 58 // Two directional lights |
| 59 SkLights::Builder builderTwoDir; |
| 60 builderTwoDir.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f,
0.0f, 1.0f), |
| 61 kLightFromUpperRight)
); |
| 62 builderTwoDir.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.0f,
1.0f, 1.0f), |
| 63 kLightFromUpperLeft))
; |
| 64 builderTwoDir.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.2f, 0.2
f, 0.2f))); |
| 65 fLightsTwoDir = builderTwoDir.finish(); |
| 66 |
51 fRect = SkRect::MakeIWH(kTexSize, kTexSize); | 67 fRect = SkRect::MakeIWH(kTexSize, kTexSize); |
52 SkMatrix matrix; | 68 SkMatrix matrix; |
53 SkRect bitmapBounds = SkRect::MakeIWH(kTexSize, kTexSize); | 69 SkRect bitmapBounds = SkRect::MakeIWH(kTexSize, kTexSize); |
54 matrix.setRectToRect(bitmapBounds, fRect, SkMatrix::kFill_ScaleToFit); | 70 matrix.setRectToRect(bitmapBounds, fRect, SkMatrix::kFill_ScaleToFit); |
55 | 71 |
56 SkBitmap opaqueDiffuseMap = sk_tool_utils::create_checkerboard_bitmap( | 72 SkBitmap opaqueDiffuseMap = sk_tool_utils::create_checkerboard_bitmap( |
57 kTexSize, kTexSize, | 73 kTexSize, kTexSize, |
58 sk_tool_utils::color_to_565(0x0), | 74 sk_tool_utils::color_to_565(0x0), |
59 sk_tool_utils::color_to_565(0xFF804020), | 75 sk_tool_utils::color_to_565(0xFF804020), |
60 8); | 76 8); |
(...skipping 19 matching lines...) Expand all Loading... |
80 void positionCTM(SkCanvas *canvas, SkScalar scaleX, SkScalar scaleY, SkScala
r rotate) const { | 96 void positionCTM(SkCanvas *canvas, SkScalar scaleX, SkScalar scaleY, SkScala
r rotate) const { |
81 canvas->translate(kTexSize/2.0f, kTexSize/2.0f); | 97 canvas->translate(kTexSize/2.0f, kTexSize/2.0f); |
82 canvas->scale(scaleX, scaleY); | 98 canvas->scale(scaleX, scaleY); |
83 canvas->rotate(rotate); | 99 canvas->rotate(rotate); |
84 canvas->translate(-kTexSize/2.0f, -kTexSize/2.0f); | 100 canvas->translate(-kTexSize/2.0f, -kTexSize/2.0f); |
85 } | 101 } |
86 | 102 |
87 static constexpr int NUM_BOOLEAN_PARAMS = 4; | 103 static constexpr int NUM_BOOLEAN_PARAMS = 4; |
88 void drawRect(SkCanvas* canvas, SkScalar scaleX, SkScalar scaleY, | 104 void drawRect(SkCanvas* canvas, SkScalar scaleX, SkScalar scaleY, |
89 SkScalar rotate, bool useNormalSource, bool useDiffuseShader, | 105 SkScalar rotate, bool useNormalSource, bool useDiffuseShader, |
90 bool useTranslucentPaint, bool useTranslucentShader) { | 106 bool useTranslucentPaint, bool useTranslucentShader, sk_sp<SkL
ights> lights) { |
91 canvas->save(); | 107 canvas->save(); |
92 | 108 |
93 this->positionCTM(canvas, scaleX, scaleY, rotate); | 109 this->positionCTM(canvas, scaleX, scaleY, rotate); |
94 | 110 |
95 const SkMatrix& ctm = canvas->getTotalMatrix(); | 111 const SkMatrix& ctm = canvas->getTotalMatrix(); |
96 | 112 |
97 SkPaint paint; | 113 SkPaint paint; |
98 sk_sp<SkNormalSource> normalSource = nullptr; | 114 sk_sp<SkNormalSource> normalSource = nullptr; |
99 sk_sp<SkShader> diffuseShader = nullptr; | 115 sk_sp<SkShader> diffuseShader = nullptr; |
100 | 116 |
101 if (useNormalSource) { | 117 if (useNormalSource) { |
102 normalSource = SkNormalSource::MakeFromNormalMap(fNormalMapShader, c
tm); | 118 normalSource = SkNormalSource::MakeFromNormalMap(fNormalMapShader, c
tm); |
103 } | 119 } |
104 | 120 |
105 if (useDiffuseShader) { | 121 if (useDiffuseShader) { |
106 diffuseShader = (useTranslucentShader) ? fTranslucentDiffuse : fOpaq
ueDiffuse; | 122 diffuseShader = (useTranslucentShader) ? fTranslucentDiffuse : fOpaq
ueDiffuse; |
107 } else { | 123 } else { |
108 paint.setColor(0xFF00FF00); | 124 paint.setColor(0xFF00FF00); |
109 } | 125 } |
110 | 126 |
111 if (useTranslucentPaint) { | 127 if (useTranslucentPaint) { |
112 paint.setAlpha(0x99); | 128 paint.setAlpha(0x99); |
113 } | 129 } |
114 | 130 |
115 paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::mo
ve(normalSource), | 131 paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::mo
ve(normalSource), |
116 fLights)); | 132 std::move(lights))); |
117 canvas->drawRect(fRect, paint); | 133 canvas->drawRect(fRect, paint); |
118 | 134 |
119 canvas->restore(); | 135 canvas->restore(); |
120 } | 136 } |
121 | 137 |
122 void onDraw(SkCanvas* canvas) override { | 138 void onDraw(SkCanvas* canvas) override { |
123 | 139 |
124 constexpr SkScalar LABEL_SIZE = 10.0f; | 140 constexpr SkScalar LABEL_SIZE = 10.0f; |
125 SkPaint labelPaint; | 141 SkPaint labelPaint; |
126 labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-ser
if", | 142 labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-ser
if", |
(...skipping 13 matching lines...) Expand all Loading... |
140 for (bool useTranslucentShader : {true, false}) { | 156 for (bool useTranslucentShader : {true, false}) { |
141 | 157 |
142 // Determining position | 158 // Determining position |
143 SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_
WIDTH; | 159 SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_
WIDTH; |
144 SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_
WIDTH; | 160 SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_
WIDTH; |
145 | 161 |
146 canvas->save(); | 162 canvas->save(); |
147 | 163 |
148 canvas->translate(xPos, yPos); | 164 canvas->translate(xPos, yPos); |
149 this->drawRect(canvas, 1.0f, 1.0f, 0.f, useNormalSource,
useDiffuseShader, | 165 this->drawRect(canvas, 1.0f, 1.0f, 0.f, useNormalSource,
useDiffuseShader, |
150 useTranslucentPaint, useTranslucentShader
); | 166 useTranslucentPaint, useTranslucentShader
, fLights); |
151 // Drawing labels | 167 // Drawing labels |
152 canvas->translate(0.0f, SkIntToScalar(kTexSize)); | 168 canvas->translate(0.0f, SkIntToScalar(kTexSize)); |
153 { | 169 { |
154 canvas->translate(0.0f, LABEL_SIZE); | 170 canvas->translate(0.0f, LABEL_SIZE); |
155 SkString label; | 171 SkString label; |
156 label.appendf("useNormalSource: %d", useNormalSource
); | 172 label.appendf("useNormalSource: %d", useNormalSource
); |
157 canvas->drawText(label.c_str(), label.size(), 0.0f,
0.0f, labelPaint); | 173 canvas->drawText(label.c_str(), label.size(), 0.0f,
0.0f, labelPaint); |
158 } | 174 } |
159 { | 175 { |
160 canvas->translate(0.0f, LABEL_SIZE); | 176 canvas->translate(0.0f, LABEL_SIZE); |
(...skipping 23 matching lines...) Expand all Loading... |
184 } | 200 } |
185 | 201 |
186 | 202 |
187 // Rotation/scale test | 203 // Rotation/scale test |
188 { | 204 { |
189 SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; | 205 SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; |
190 SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; | 206 SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; |
191 | 207 |
192 canvas->save(); | 208 canvas->save(); |
193 canvas->translate(xPos, yPos); | 209 canvas->translate(xPos, yPos); |
194 this->drawRect(canvas, 0.6f, 0.6f, 45.0f, true, true, true, true); | 210 this->drawRect(canvas, 0.6f, 0.6f, 45.0f, true, true, true, true, fL
ights); |
195 canvas->restore(); | 211 canvas->restore(); |
196 | 212 |
197 gridNum++; | 213 gridNum++; |
198 } | 214 } |
199 | 215 |
200 // Anisotropic scale test | 216 // Anisotropic scale test |
201 { | 217 { |
202 SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; | 218 SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; |
203 SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; | 219 SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; |
204 | 220 |
205 canvas->save(); | 221 canvas->save(); |
206 canvas->translate(xPos, yPos); | 222 canvas->translate(xPos, yPos); |
207 this->drawRect(canvas, 0.6f, 0.4f, 30.0f, true, true, true, true); | 223 this->drawRect(canvas, 0.6f, 0.4f, 30.0f, true, true, true, true, fL
ights); |
208 canvas->restore(); | 224 canvas->restore(); |
209 | 225 |
210 gridNum++; | 226 gridNum++; |
| 227 } |
| 228 |
| 229 // No directional lights test |
| 230 { |
| 231 SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; |
| 232 SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; |
| 233 |
| 234 canvas->save(); |
| 235 canvas->translate(xPos, yPos); |
| 236 this->drawRect(canvas, 1.0f, 1.0f, 0.0f, true, true, false, false, f
LightsNoDir); |
| 237 canvas->restore(); |
| 238 |
| 239 gridNum++; |
| 240 } |
| 241 |
| 242 // Two directional lights test |
| 243 { |
| 244 SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; |
| 245 SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; |
| 246 |
| 247 canvas->save(); |
| 248 canvas->translate(xPos, yPos); |
| 249 this->drawRect(canvas, 1.0f, 1.0f, 0.0f, true, true, false, false, f
LightsTwoDir); |
| 250 canvas->restore(); |
| 251 |
| 252 gridNum++; |
211 } | 253 } |
212 } | 254 } |
213 | 255 |
214 private: | 256 private: |
215 static const int kTexSize = 96; | 257 static const int kTexSize = 96; |
216 | 258 |
217 sk_sp<SkShader> fOpaqueDiffuse; | 259 sk_sp<SkShader> fOpaqueDiffuse; |
218 sk_sp<SkShader> fTranslucentDiffuse; | 260 sk_sp<SkShader> fTranslucentDiffuse; |
219 sk_sp<SkShader> fNormalMapShader; | 261 sk_sp<SkShader> fNormalMapShader; |
220 | 262 |
221 SkRect fRect; | 263 SkRect fRect; |
222 sk_sp<SkLights> fLights; | 264 sk_sp<SkLights> fLights; |
| 265 sk_sp<SkLights> fLightsNoDir; |
| 266 sk_sp<SkLights> fLightsTwoDir; |
223 | 267 |
224 typedef GM INHERITED; | 268 typedef GM INHERITED; |
225 }; | 269 }; |
226 | 270 |
227 ////////////////////////////////////////////////////////////////////////////// | 271 ////////////////////////////////////////////////////////////////////////////// |
228 | 272 |
229 DEF_GM(return new LightingShader2GM;) | 273 DEF_GM(return new LightingShader2GM;) |
230 } | 274 } |
OLD | NEW |