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