| 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 |