1 /* 2 * Copyright 2012 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 #include "sk_tool_utils.h" 10 #include "SkAnimTimer.h" 11 #include "SkLightingImageFilter.h" 12 #include "SkOffsetImageFilter.h" 13 #include "SkPoint3.h" 14 15 #define WIDTH 330 16 #define HEIGHT 660 17 18 namespace skiagm { 19 20 class ImageLightingGM : public GM { 21 public: ImageLightingGM()22 ImageLightingGM() 23 : fAzimuth(SkIntToScalar(kStartAzimuth)) { 24 this->setBGColor(0xFF000000); 25 } 26 27 protected: 28 onShortName()29 SkString onShortName() override { 30 return SkString("lighting"); 31 } 32 onISize()33 SkISize onISize() override { 34 return SkISize::Make(WIDTH, HEIGHT); 35 } 36 drawClippedBitmap(SkCanvas * canvas,const SkPaint & paint,int x,int y)37 void drawClippedBitmap(SkCanvas* canvas, const SkPaint& paint, int x, int y) { 38 canvas->save(); 39 canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); 40 canvas->clipRect(SkRect::MakeWH( 41 SkIntToScalar(fBitmap.width()), SkIntToScalar(fBitmap.height()))); 42 canvas->drawBitmap(fBitmap, 0, 0, &paint); 43 canvas->restore(); 44 } 45 onOnceBeforeDraw()46 void onOnceBeforeDraw() override { 47 fBitmap = sk_tool_utils::create_string_bitmap(100, 100, 0xFFFFFFFF, 20, 70, 96, "e"); 48 } 49 onDraw(SkCanvas * canvas)50 void onDraw(SkCanvas* canvas) override { 51 canvas->clear(0xFF101010); 52 SkPaint checkPaint; 53 checkPaint.setColor(0xFF202020); 54 for (int y = 0; y < HEIGHT; y += 16) { 55 for (int x = 0; x < WIDTH; x += 16) { 56 canvas->save(); 57 canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); 58 canvas->drawRect(SkRect::MakeXYWH(8, 0, 8, 8), checkPaint); 59 canvas->drawRect(SkRect::MakeXYWH(0, 8, 8, 8), checkPaint); 60 canvas->restore(); 61 } 62 } 63 SkScalar cosAzimuth; 64 SkScalar sinAzimuth = SkScalarSinCos(SkDegreesToRadians(fAzimuth), &cosAzimuth); 65 66 SkPoint3 spotTarget = SkPoint3::Make(SkIntToScalar(40), SkIntToScalar(40), 0); 67 SkPoint3 spotLocation = SkPoint3::Make(spotTarget.fX + 70.7214f * cosAzimuth, 68 spotTarget.fY + 70.7214f * sinAzimuth, 69 spotTarget.fZ + SkIntToScalar(20)); 70 SkScalar spotExponent = SK_Scalar1; 71 72 SkPoint3 pointLocation = SkPoint3::Make(spotTarget.fX + 50 * cosAzimuth, 73 spotTarget.fY + 50 * sinAzimuth, 74 SkIntToScalar(10)); 75 SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5)); 76 77 SkPoint3 distantDirection = SkPoint3::Make(cosAzimuth * SkScalarCos(elevationRad), 78 sinAzimuth * SkScalarCos(elevationRad), 79 SkScalarSin(elevationRad)); 80 SkScalar cutoffAngle = SkIntToScalar(15); 81 SkScalar kd = SkIntToScalar(2); 82 SkScalar ks = SkIntToScalar(1); 83 SkScalar shininess = SkIntToScalar(8); 84 SkScalar surfaceScale = SkIntToScalar(1); 85 SkColor white(0xFFFFFFFF); 86 SkPaint paint; 87 88 SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(20, 10, 60, 65)); 89 SkImageFilter::CropRect fullSizeCropRect(SkRect::MakeXYWH(0, 0, 100, 100)); 90 sk_sp<SkImageFilter> noopCropped(SkOffsetImageFilter::Make(0, 0, nullptr, &cropRect)); 91 92 int y = 0; 93 for (int i = 0; i < 3; i++) { 94 const SkImageFilter::CropRect* cr = (i == 1) ? &cropRect : (i == 2) ? &fullSizeCropRect : nullptr; 95 sk_sp<SkImageFilter> input = (i == 2) ? noopCropped : nullptr; 96 paint.setImageFilter(SkLightingImageFilter::MakePointLitDiffuse(pointLocation, 97 white, 98 surfaceScale, 99 kd, 100 input, 101 cr)); 102 drawClippedBitmap(canvas, paint, 0, y); 103 104 paint.setImageFilter(SkLightingImageFilter::MakeDistantLitDiffuse(distantDirection, 105 white, 106 surfaceScale, 107 kd, 108 input, 109 cr)); 110 drawClippedBitmap(canvas, paint, 110, y); 111 112 paint.setImageFilter(SkLightingImageFilter::MakeSpotLitDiffuse(spotLocation, 113 spotTarget, 114 spotExponent, 115 cutoffAngle, 116 white, 117 surfaceScale, 118 kd, 119 input, 120 cr)); 121 drawClippedBitmap(canvas, paint, 220, y); 122 123 y += 110; 124 125 paint.setImageFilter(SkLightingImageFilter::MakePointLitSpecular(pointLocation, 126 white, 127 surfaceScale, 128 ks, 129 shininess, 130 input, 131 cr)); 132 drawClippedBitmap(canvas, paint, 0, y); 133 134 paint.setImageFilter(SkLightingImageFilter::MakeDistantLitSpecular(distantDirection, 135 white, 136 surfaceScale, 137 ks, 138 shininess, 139 input, 140 cr)); 141 drawClippedBitmap(canvas, paint, 110, y); 142 143 paint.setImageFilter(SkLightingImageFilter::MakeSpotLitSpecular(spotLocation, 144 spotTarget, 145 spotExponent, 146 cutoffAngle, 147 white, 148 surfaceScale, 149 ks, 150 shininess, 151 input, 152 cr)); 153 drawClippedBitmap(canvas, paint, 220, y); 154 155 y += 110; 156 } 157 } 158 onAnimate(const SkAnimTimer & timer)159 bool onAnimate(const SkAnimTimer& timer) override { 160 constexpr SkScalar kDesiredDurationSecs = 15.0f; 161 162 fAzimuth = kStartAzimuth + timer.scaled(360.0f/kDesiredDurationSecs, 360.0f); 163 return true; 164 } 165 166 private: 167 static constexpr int kStartAzimuth = 225; 168 169 SkBitmap fBitmap; 170 SkScalar fAzimuth; 171 172 typedef GM INHERITED; 173 }; 174 175 ////////////////////////////////////////////////////////////////////////////// 176 177 DEF_GM(return new ImageLightingGM;) 178 } 179