| 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 "SampleCode.h" | 8 #include "SampleCode.h" |
| 9 #include "SkAnimTimer.h" | 9 #include "SkAnimTimer.h" |
| 10 #include "SkView.h" | 10 #include "SkView.h" |
| 11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
| 12 #include "SkDrawable.h" | 12 #include "SkDrawable.h" |
| 13 #include "SkLightingShader.h" | 13 #include "SkLightingShader.h" |
| 14 #include "SkLights.h" | 14 #include "SkLights.h" |
| 15 #include "SkRandom.h" | 15 #include "SkRandom.h" |
| 16 #include "SkRSXform.h" | 16 #include "SkRSXform.h" |
| 17 | 17 |
| 18 #include "sk_tool_utils.h" | 18 #include "sk_tool_utils.h" |
| 19 | 19 |
| 20 class DrawLitAtlasDrawable : public SkDrawable { | 20 class DrawLitAtlasDrawable : public SkDrawable { |
| 21 public: | 21 public: |
| 22 DrawLitAtlasDrawable(const SkRect& r) | 22 DrawLitAtlasDrawable(const SkRect& r) |
| 23 : fBounds(r) | 23 : fBounds(r) |
| 24 , fUseColors(false) { | 24 , fUseColors(false) |
| 25 , fLightDir(SkVector3::Make(1.0f, 0.0f, 0.0f)) { |
| 25 fAtlas = MakeAtlas(); | 26 fAtlas = MakeAtlas(); |
| 26 | 27 |
| 27 SkRandom rand; | 28 SkRandom rand; |
| 28 for (int i = 0; i < kNumAsteroids; ++i) { | 29 for (int i = 0; i < kNumAsteroids; ++i) { |
| 29 fAsteroids[i].initAsteroid(&rand, fBounds, &fDiffTex[i], &fNormTex[i
]); | 30 fAsteroids[i].initAsteroid(&rand, fBounds, &fDiffTex[i], &fNormTex[i
]); |
| 30 } | 31 } |
| 31 | 32 |
| 32 fShip.initShip(fBounds, &fDiffTex[kNumAsteroids], &fNormTex[kNumAsteroid
s]); | 33 fShip.initShip(fBounds, &fDiffTex[kNumAsteroids], &fNormTex[kNumAsteroid
s]); |
| 33 | 34 |
| 34 SkLights::Builder builder; | 35 this->updateLights(); |
| 35 | |
| 36 builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f), | |
| 37 SkVector3::Make(1.0f, 0.0f, 0.0f))); | |
| 38 builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f))); | |
| 39 | |
| 40 fLights = builder.finish(); | |
| 41 } | 36 } |
| 42 | 37 |
| 43 void toggleUseColors() { | 38 void toggleUseColors() { |
| 44 fUseColors = !fUseColors; | 39 fUseColors = !fUseColors; |
| 45 } | 40 } |
| 46 | 41 |
| 42 void rotateLight() { |
| 43 SkScalar c; |
| 44 SkScalar s = SkScalarSinCos(SK_ScalarPI/6.0f, &c); |
| 45 |
| 46 SkScalar newX = c * fLightDir.fX - s * fLightDir.fY; |
| 47 SkScalar newY = s * fLightDir.fX + c * fLightDir.fY; |
| 48 |
| 49 fLightDir.set(newX, newY, 0.0f); |
| 50 |
| 51 this->updateLights(); |
| 52 } |
| 53 |
| 47 void left() { | 54 void left() { |
| 48 SkScalar newRot = SkScalarMod(fShip.rot() + (2*SK_ScalarPI - SK_ScalarPI
/32.0f), | 55 SkScalar newRot = SkScalarMod(fShip.rot() + (2*SK_ScalarPI - SK_ScalarPI
/32.0f), |
| 49 2 * SK_ScalarPI); | 56 2 * SK_ScalarPI); |
| 50 fShip.setRot(newRot); | 57 fShip.setRot(newRot); |
| 51 } | 58 } |
| 52 | 59 |
| 53 void right() { | 60 void right() { |
| 54 SkScalar newRot = SkScalarMod(fShip.rot() + SK_ScalarPI/32.0f, 2 * SK_Sc
alarPI); | 61 SkScalar newRot = SkScalarMod(fShip.rot() + SK_ScalarPI/32.0f, 2 * SK_Sc
alarPI); |
| 55 fShip.setRot(newRot); | 62 fShip.setRot(newRot); |
| 56 } | 63 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 84 } | 91 } |
| 85 | 92 |
| 86 fShip.advance(fBounds); | 93 fShip.advance(fBounds); |
| 87 xforms[kNumAsteroids] = fShip.asRSXform(); | 94 xforms[kNumAsteroids] = fShip.asRSXform(); |
| 88 if (fUseColors) { | 95 if (fUseColors) { |
| 89 colors[kNumAsteroids] = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF); | 96 colors[kNumAsteroids] = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF); |
| 90 } | 97 } |
| 91 | 98 |
| 92 #ifdef SK_DEBUG | 99 #ifdef SK_DEBUG |
| 93 canvas->drawBitmap(fAtlas, 0, 0); // just to see the atlas | 100 canvas->drawBitmap(fAtlas, 0, 0); // just to see the atlas |
| 94 #endif | 101 |
| 102 this->drawLightDir(canvas, fBounds.centerX(), fBounds.centerY()); |
| 103 #endif |
| 95 | 104 |
| 96 #if 0 | 105 #if 0 |
| 97 // TODO: revitalize when drawLitAtlas API lands | 106 // TODO: revitalize when drawLitAtlas API lands |
| 98 SkPaint paint; | 107 SkPaint paint; |
| 99 paint.setFilterQuality(kLow_SkFilterQuality); | 108 paint.setFilterQuality(kLow_SkFilterQuality); |
| 100 | 109 |
| 101 const SkRect cull = this->getBounds(); | 110 const SkRect cull = this->getBounds(); |
| 102 const SkColor* colorsPtr = fUseColors ? colors : NULL; | 111 const SkColor* colorsPtr = fUseColors ? colors : NULL; |
| 103 | 112 |
| 104 canvas->drawLitAtlas(fAtlas, xforms, fDiffTex, fNormTex, colorsPtr, kNum
Asteroids+1, | 113 canvas->drawLitAtlas(fAtlas, xforms, fDiffTex, fNormTex, colorsPtr, kNum
Asteroids+1, |
| 105 SkXfermode::kModulate_Mode, &cull, &paint, fLights)
; | 114 SkXfermode::kModulate_Mode, &cull, &paint, fLights)
; |
| 106 #else | 115 #else |
| 107 SkMatrix diffMat, normalMat; | 116 SkMatrix diffMat, normalMat; |
| 108 | 117 |
| 109 for (int i = 0; i < kNumAsteroids+1; ++i) { | 118 for (int i = 0; i < kNumAsteroids+1; ++i) { |
| 110 colors[i] = colors[i] & 0xFF000000; // to silence compilers | 119 colors[i] = colors[i] & 0xFF000000; // to silence compilers |
| 111 SkPaint paint; | 120 SkPaint paint; |
| 112 | 121 |
| 113 SkRect r = fDiffTex[i]; | 122 SkRect r = fDiffTex[i]; |
| 114 r.offsetTo(0, 0); | 123 r.offsetTo(0, 0); |
| 115 | 124 |
| 116 diffMat.setRectToRect(fDiffTex[i], r, SkMatrix::kFill_ScaleToFit); | 125 diffMat.setRectToRect(fDiffTex[i], r, SkMatrix::kFill_ScaleToFit); |
| 117 normalMat.setRectToRect(fNormTex[i], r, SkMatrix::kFill_ScaleToFit); | 126 normalMat.setRectToRect(fNormTex[i], r, SkMatrix::kFill_ScaleToFit); |
| 118 | 127 |
| 119 SkMatrix m; | 128 SkMatrix m; |
| 120 m.setRSXform(xforms[i]); | 129 m.setRSXform(xforms[i]); |
| 121 | 130 |
| 122 // TODO: correctly pull out the pure rotation | 131 // TODO: correctly pull out the pure rotation |
| 123 SkVector invNormRotation = { m[SkMatrix::kMScaleX], m[SkMatrix::kMSk
ewY] }; | 132 SkVector invNormRotation = { m[SkMatrix::kMScaleX], m[SkMatrix::kMSk
ewY] }; |
| 133 SkASSERT(SkScalarNearlyEqual(invNormRotation.lengthSqd(), SK_Scalar1
)); |
| 124 | 134 |
| 125 paint.setShader(SkLightingShader::Make(fAtlas, fAtlas, fLights, | 135 paint.setShader(SkLightingShader::Make(fAtlas, fAtlas, fLights, |
| 126 invNormRotation, &diffMat, &n
ormalMat)); | 136 invNormRotation, &diffMat, &n
ormalMat)); |
| 127 | 137 |
| 128 canvas->save(); | 138 canvas->save(); |
| 129 canvas->setMatrix(m); | 139 canvas->setMatrix(m); |
| 130 canvas->drawRect(r, paint); | 140 canvas->drawRect(r, paint); |
| 131 canvas->restore(); | 141 canvas->restore(); |
| 132 } | 142 } |
| 133 #endif | 143 #endif |
| (...skipping 24 matching lines...) Expand all Loading... |
| 158 kBigAsteroid_ObjType = 0, | 168 kBigAsteroid_ObjType = 0, |
| 159 kMedAsteroid_ObjType, | 169 kMedAsteroid_ObjType, |
| 160 kSmAsteroid_ObjType, | 170 kSmAsteroid_ObjType, |
| 161 kShip_ObjType, | 171 kShip_ObjType, |
| 162 | 172 |
| 163 kLast_ObjType = kShip_ObjType | 173 kLast_ObjType = kShip_ObjType |
| 164 }; | 174 }; |
| 165 | 175 |
| 166 static const int kObjTypeCount = kLast_ObjType + 1; | 176 static const int kObjTypeCount = kLast_ObjType + 1; |
| 167 | 177 |
| 178 void updateLights() { |
| 179 SkLights::Builder builder; |
| 180 |
| 181 builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f), fLightDir
)); |
| 182 builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f))); |
| 183 |
| 184 fLights = builder.finish(); |
| 185 } |
| 186 |
| 187 #ifdef SK_DEBUG |
| 188 // Draw a vector to the light |
| 189 void drawLightDir(SkCanvas* canvas, SkScalar centerX, SkScalar centerY) { |
| 190 static const int kBgLen = 30; |
| 191 static const int kSmLen = 5; |
| 192 |
| 193 // TODO: change the lighting coordinate system to be right handed |
| 194 SkPoint p1 = SkPoint::Make(centerX + kBgLen * fLightDir.fX, |
| 195 centerY - kBgLen * fLightDir.fY); |
| 196 SkPoint p2 = SkPoint::Make(centerX + (kBgLen-kSmLen) * fLightDir.fX, |
| 197 centerY - (kBgLen-kSmLen) * fLightDir.fY); |
| 198 |
| 199 SkPaint p; |
| 200 canvas->drawLine(centerX, centerY, p1.fX, p1.fY, p); |
| 201 canvas->drawLine(p1.fX, p1.fY, |
| 202 p2.fX - kSmLen * fLightDir.fY, p2.fY - kSmLen * fLightD
ir.fX, p); |
| 203 canvas->drawLine(p1.fX, p1.fY, |
| 204 p2.fX + kSmLen * fLightDir.fY, p2.fY + kSmLen * fLightD
ir.fX, p); |
| 205 } |
| 206 #endif |
| 207 |
| 168 // Create the mixed diffuse & normal atlas | 208 // Create the mixed diffuse & normal atlas |
| 169 // | 209 // |
| 170 // big color circle | big normal hemi | 210 // big color circle | big normal hemi |
| 171 // ------------------------------------ | 211 // ------------------------------------ |
| 172 // med color circle | med normal pyra | 212 // med color circle | med normal pyra |
| 173 // ------------------------------------ | 213 // ------------------------------------ |
| 174 // sm color circle | sm normal hemi | 214 // sm color circle | sm normal hemi |
| 175 // ------------------------------------ | 215 // ------------------------------------ |
| 176 // big ship | big tetra normal | 216 // big ship | big tetra normal |
| 177 static SkBitmap MakeAtlas() { | 217 static SkBitmap MakeAtlas() { |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 static const int kShipYOff = kSmYOff + kSmSize + kPad; | 431 static const int kShipYOff = kSmYOff + kSmSize + kPad; |
| 392 static const int kMaxShipSpeed = 5; | 432 static const int kMaxShipSpeed = 5; |
| 393 | 433 |
| 394 SkBitmap fAtlas; | 434 SkBitmap fAtlas; |
| 395 ObjectRecord fAsteroids[kNumAsteroids]; | 435 ObjectRecord fAsteroids[kNumAsteroids]; |
| 396 ObjectRecord fShip; | 436 ObjectRecord fShip; |
| 397 SkRect fDiffTex[kNumAsteroids+kNumShips]; | 437 SkRect fDiffTex[kNumAsteroids+kNumShips]; |
| 398 SkRect fNormTex[kNumAsteroids+kNumShips]; | 438 SkRect fNormTex[kNumAsteroids+kNumShips]; |
| 399 SkRect fBounds; | 439 SkRect fBounds; |
| 400 bool fUseColors; | 440 bool fUseColors; |
| 441 SkVector3 fLightDir; |
| 401 sk_sp<SkLights> fLights; | 442 sk_sp<SkLights> fLights; |
| 402 | 443 |
| 403 typedef SkDrawable INHERITED; | 444 typedef SkDrawable INHERITED; |
| 404 }; | 445 }; |
| 405 | 446 |
| 406 class DrawLitAtlasView : public SampleView { | 447 class DrawLitAtlasView : public SampleView { |
| 407 public: | 448 public: |
| 408 DrawLitAtlasView() | 449 DrawLitAtlasView() |
| 409 : fDrawable(new DrawLitAtlasDrawable(SkRect::MakeWH(640, 480))) { | 450 : fDrawable(new DrawLitAtlasDrawable(SkRect::MakeWH(640, 480))) { |
| 410 } | 451 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 427 this->inval(NULL); | 468 this->inval(NULL); |
| 428 return true; | 469 return true; |
| 429 case 'k': | 470 case 'k': |
| 430 fDrawable->thrust(); | 471 fDrawable->thrust(); |
| 431 this->inval(NULL); | 472 this->inval(NULL); |
| 432 return true; | 473 return true; |
| 433 case 'l': | 474 case 'l': |
| 434 fDrawable->right(); | 475 fDrawable->right(); |
| 435 this->inval(NULL); | 476 this->inval(NULL); |
| 436 return true; | 477 return true; |
| 478 case 'o': |
| 479 fDrawable->rotateLight(); |
| 480 this->inval(NULL); |
| 481 return true; |
| 437 default: | 482 default: |
| 438 break; | 483 break; |
| 439 } | 484 } |
| 440 } | 485 } |
| 441 return this->INHERITED::onQuery(evt); | 486 return this->INHERITED::onQuery(evt); |
| 442 } | 487 } |
| 443 | 488 |
| 444 void onDrawContent(SkCanvas* canvas) override { | 489 void onDrawContent(SkCanvas* canvas) override { |
| 445 canvas->drawDrawable(fDrawable); | 490 canvas->drawDrawable(fDrawable); |
| 446 this->inval(NULL); | 491 this->inval(NULL); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 458 private: | 503 private: |
| 459 SkAutoTUnref<DrawLitAtlasDrawable> fDrawable; | 504 SkAutoTUnref<DrawLitAtlasDrawable> fDrawable; |
| 460 | 505 |
| 461 typedef SampleView INHERITED; | 506 typedef SampleView INHERITED; |
| 462 }; | 507 }; |
| 463 | 508 |
| 464 ////////////////////////////////////////////////////////////////////////////// | 509 ////////////////////////////////////////////////////////////////////////////// |
| 465 | 510 |
| 466 static SkView* MyFactory() { return new DrawLitAtlasView; } | 511 static SkView* MyFactory() { return new DrawLitAtlasView; } |
| 467 static SkViewRegister reg(MyFactory); | 512 static SkViewRegister reg(MyFactory); |
| OLD | NEW |