1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2012 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageFilter.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint3.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkImageFilters.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h" 23*c8dee2aaSAndroid Build Coastguard Worker #include "tools/timer/TimeUtils.h" 24*c8dee2aaSAndroid Build Coastguard Worker 25*c8dee2aaSAndroid Build Coastguard Worker #define WIDTH 660 26*c8dee2aaSAndroid Build Coastguard Worker #define HEIGHT 660 27*c8dee2aaSAndroid Build Coastguard Worker 28*c8dee2aaSAndroid Build Coastguard Worker namespace skiagm { 29*c8dee2aaSAndroid Build Coastguard Worker 30*c8dee2aaSAndroid Build Coastguard Worker class ImageLightingGM : public GM { 31*c8dee2aaSAndroid Build Coastguard Worker public: ImageLightingGM()32*c8dee2aaSAndroid Build Coastguard Worker ImageLightingGM() 33*c8dee2aaSAndroid Build Coastguard Worker : fAzimuth(SkIntToScalar(kStartAzimuth)) { 34*c8dee2aaSAndroid Build Coastguard Worker this->setBGColor(0xFF000000); 35*c8dee2aaSAndroid Build Coastguard Worker } 36*c8dee2aaSAndroid Build Coastguard Worker 37*c8dee2aaSAndroid Build Coastguard Worker protected: getName() const38*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("lighting"); } 39*c8dee2aaSAndroid Build Coastguard Worker getISize()40*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(WIDTH, HEIGHT); } 41*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(SkCanvas * canvas,const SkPaint & paint,int x,int y)42*c8dee2aaSAndroid Build Coastguard Worker void drawClippedBitmap(SkCanvas* canvas, const SkPaint& paint, int x, int y) { 43*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 44*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); 45*c8dee2aaSAndroid Build Coastguard Worker canvas->clipIRect(fBitmap.bounds()); 46*c8dee2aaSAndroid Build Coastguard Worker canvas->drawImage(fBitmap.asImage(), 0, 0, SkSamplingOptions(), &paint); 47*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 48*c8dee2aaSAndroid Build Coastguard Worker } 49*c8dee2aaSAndroid Build Coastguard Worker onOnceBeforeDraw()50*c8dee2aaSAndroid Build Coastguard Worker void onOnceBeforeDraw() override { 51*c8dee2aaSAndroid Build Coastguard Worker fBitmap = ToolUtils::CreateStringBitmap(100, 100, 0xFFFFFFFF, 20, 70, 96, "e"); 52*c8dee2aaSAndroid Build Coastguard Worker } 53*c8dee2aaSAndroid Build Coastguard Worker onDraw(SkCanvas * canvas)54*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override { 55*c8dee2aaSAndroid Build Coastguard Worker canvas->clear(0xFF101010); 56*c8dee2aaSAndroid Build Coastguard Worker SkPaint checkPaint; 57*c8dee2aaSAndroid Build Coastguard Worker checkPaint.setColor(0xFF202020); 58*c8dee2aaSAndroid Build Coastguard Worker for (int y = 0; y < HEIGHT; y += 16) { 59*c8dee2aaSAndroid Build Coastguard Worker for (int x = 0; x < WIDTH; x += 16) { 60*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 61*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); 62*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(SkRect::MakeXYWH(8, 0, 8, 8), checkPaint); 63*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(SkRect::MakeXYWH(0, 8, 8, 8), checkPaint); 64*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 65*c8dee2aaSAndroid Build Coastguard Worker } 66*c8dee2aaSAndroid Build Coastguard Worker } 67*c8dee2aaSAndroid Build Coastguard Worker SkScalar sinAzimuth = SkScalarSin(SkDegreesToRadians(fAzimuth)), 68*c8dee2aaSAndroid Build Coastguard Worker cosAzimuth = SkScalarCos(SkDegreesToRadians(fAzimuth)); 69*c8dee2aaSAndroid Build Coastguard Worker 70*c8dee2aaSAndroid Build Coastguard Worker SkPoint3 spotTarget = SkPoint3::Make(SkIntToScalar(40), SkIntToScalar(40), 0); 71*c8dee2aaSAndroid Build Coastguard Worker SkPoint3 spotLocation = SkPoint3::Make(spotTarget.fX + 70.7214f * cosAzimuth, 72*c8dee2aaSAndroid Build Coastguard Worker spotTarget.fY + 70.7214f * sinAzimuth, 73*c8dee2aaSAndroid Build Coastguard Worker spotTarget.fZ + SkIntToScalar(20)); 74*c8dee2aaSAndroid Build Coastguard Worker SkScalar spotExponent1 = SK_Scalar1; 75*c8dee2aaSAndroid Build Coastguard Worker SkScalar spotExponent10 = SkIntToScalar(10); 76*c8dee2aaSAndroid Build Coastguard Worker SkScalar cutoffAngleSmall = SkIntToScalar(15); 77*c8dee2aaSAndroid Build Coastguard Worker SkScalar cutoffAngleNone = SkIntToScalar(180); 78*c8dee2aaSAndroid Build Coastguard Worker 79*c8dee2aaSAndroid Build Coastguard Worker SkPoint3 pointLocation = SkPoint3::Make(spotTarget.fX + 50 * cosAzimuth, 80*c8dee2aaSAndroid Build Coastguard Worker spotTarget.fY + 50 * sinAzimuth, 81*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(10)); 82*c8dee2aaSAndroid Build Coastguard Worker SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5)); 83*c8dee2aaSAndroid Build Coastguard Worker 84*c8dee2aaSAndroid Build Coastguard Worker SkPoint3 distantDirection = SkPoint3::Make(cosAzimuth * SkScalarCos(elevationRad), 85*c8dee2aaSAndroid Build Coastguard Worker sinAzimuth * SkScalarCos(elevationRad), 86*c8dee2aaSAndroid Build Coastguard Worker SkScalarSin(elevationRad)); 87*c8dee2aaSAndroid Build Coastguard Worker SkScalar kd = SkIntToScalar(2); 88*c8dee2aaSAndroid Build Coastguard Worker SkScalar ks = SkIntToScalar(1); 89*c8dee2aaSAndroid Build Coastguard Worker SkScalar shininess = SkIntToScalar(8); 90*c8dee2aaSAndroid Build Coastguard Worker SkScalar surfaceScale = SkIntToScalar(1); 91*c8dee2aaSAndroid Build Coastguard Worker SkScalar surfaceScaleSmall = 0.1f; 92*c8dee2aaSAndroid Build Coastguard Worker SkColor greenYellow = SkColorSetARGB(255, 173, 255, 47); 93*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 94*c8dee2aaSAndroid Build Coastguard Worker 95*c8dee2aaSAndroid Build Coastguard Worker SkIRect cropRect = SkIRect::MakeXYWH(20, 10, 60, 65); 96*c8dee2aaSAndroid Build Coastguard Worker SkIRect fullSizeCropRect = SkIRect::MakeXYWH(0, 0, 100, 100); 97*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> noopCropped(SkImageFilters::Offset(0, 0, nullptr, &cropRect)); 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker int y = 0; 100*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < 3; i++) { 101*c8dee2aaSAndroid Build Coastguard Worker const SkIRect* cr = (i == 1) ? &cropRect : (i == 2) ? &fullSizeCropRect : nullptr; 102*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImageFilter> input = (i == 2) ? noopCropped : nullptr; 103*c8dee2aaSAndroid Build Coastguard Worker // Basic point, distant and spot lights with diffuse lighting 104*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::PointLitDiffuse( 105*c8dee2aaSAndroid Build Coastguard Worker pointLocation, SK_ColorWHITE, surfaceScale, kd, input, cr)); 106*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 0, y); 107*c8dee2aaSAndroid Build Coastguard Worker 108*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::DistantLitDiffuse( 109*c8dee2aaSAndroid Build Coastguard Worker distantDirection, SK_ColorWHITE, surfaceScale, kd, input, cr)); 110*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 110, y); 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::SpotLitDiffuse( 113*c8dee2aaSAndroid Build Coastguard Worker spotLocation, spotTarget, spotExponent1, cutoffAngleSmall, SK_ColorWHITE, 114*c8dee2aaSAndroid Build Coastguard Worker surfaceScale, kd, input, cr)); 115*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 220, y); 116*c8dee2aaSAndroid Build Coastguard Worker 117*c8dee2aaSAndroid Build Coastguard Worker // Spot light with no angle cutoff 118*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::SpotLitDiffuse( 119*c8dee2aaSAndroid Build Coastguard Worker spotLocation, spotTarget, spotExponent10, cutoffAngleNone, SK_ColorWHITE, 120*c8dee2aaSAndroid Build Coastguard Worker surfaceScale, kd, input, cr)); 121*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 330, y); 122*c8dee2aaSAndroid Build Coastguard Worker 123*c8dee2aaSAndroid Build Coastguard Worker // Spot light with falloff exponent 124*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::SpotLitDiffuse( 125*c8dee2aaSAndroid Build Coastguard Worker spotLocation, spotTarget, spotExponent1, cutoffAngleNone, SK_ColorWHITE, 126*c8dee2aaSAndroid Build Coastguard Worker surfaceScaleSmall, kd, input, cr)); 127*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 440, y); 128*c8dee2aaSAndroid Build Coastguard Worker 129*c8dee2aaSAndroid Build Coastguard Worker // Large constant to show oversaturation 130*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::DistantLitDiffuse( 131*c8dee2aaSAndroid Build Coastguard Worker distantDirection, greenYellow, surfaceScale, 4.f * kd, input, cr)); 132*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 550, y); 133*c8dee2aaSAndroid Build Coastguard Worker 134*c8dee2aaSAndroid Build Coastguard Worker y += 110; 135*c8dee2aaSAndroid Build Coastguard Worker 136*c8dee2aaSAndroid Build Coastguard Worker // Basic point, distant and spot lights with specular lighting 137*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::PointLitSpecular( 138*c8dee2aaSAndroid Build Coastguard Worker pointLocation, SK_ColorWHITE, surfaceScale, ks, shininess, input, cr)); 139*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 0, y); 140*c8dee2aaSAndroid Build Coastguard Worker 141*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::DistantLitSpecular( 142*c8dee2aaSAndroid Build Coastguard Worker distantDirection, SK_ColorWHITE, surfaceScale, ks, shininess, input, cr)); 143*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 110, y); 144*c8dee2aaSAndroid Build Coastguard Worker 145*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::SpotLitSpecular( 146*c8dee2aaSAndroid Build Coastguard Worker spotLocation, spotTarget, spotExponent1, cutoffAngleSmall, SK_ColorWHITE, 147*c8dee2aaSAndroid Build Coastguard Worker surfaceScale, ks, shininess, input, cr)); 148*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 220, y); 149*c8dee2aaSAndroid Build Coastguard Worker 150*c8dee2aaSAndroid Build Coastguard Worker // Spot light with no angle cutoff 151*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::SpotLitSpecular( 152*c8dee2aaSAndroid Build Coastguard Worker spotLocation, spotTarget, spotExponent10, cutoffAngleNone, SK_ColorWHITE, 153*c8dee2aaSAndroid Build Coastguard Worker surfaceScale, ks, shininess, input, cr)); 154*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 330, y); 155*c8dee2aaSAndroid Build Coastguard Worker 156*c8dee2aaSAndroid Build Coastguard Worker // Spot light with falloff exponent 157*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::SpotLitSpecular( 158*c8dee2aaSAndroid Build Coastguard Worker spotLocation, spotTarget, spotExponent1, cutoffAngleNone, SK_ColorWHITE, 159*c8dee2aaSAndroid Build Coastguard Worker surfaceScaleSmall, ks, shininess, input, cr)); 160*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 440, y); 161*c8dee2aaSAndroid Build Coastguard Worker 162*c8dee2aaSAndroid Build Coastguard Worker // Large constant to show oversaturation 163*c8dee2aaSAndroid Build Coastguard Worker paint.setImageFilter(SkImageFilters::DistantLitSpecular( 164*c8dee2aaSAndroid Build Coastguard Worker distantDirection, greenYellow, surfaceScale, 4.f * ks, shininess, input, cr)); 165*c8dee2aaSAndroid Build Coastguard Worker drawClippedBitmap(canvas, paint, 550, y); 166*c8dee2aaSAndroid Build Coastguard Worker 167*c8dee2aaSAndroid Build Coastguard Worker y += 110; 168*c8dee2aaSAndroid Build Coastguard Worker } 169*c8dee2aaSAndroid Build Coastguard Worker } 170*c8dee2aaSAndroid Build Coastguard Worker onAnimate(double nanos)171*c8dee2aaSAndroid Build Coastguard Worker bool onAnimate(double nanos) override { 172*c8dee2aaSAndroid Build Coastguard Worker constexpr SkScalar kDesiredDurationSecs = 15.0f; 173*c8dee2aaSAndroid Build Coastguard Worker 174*c8dee2aaSAndroid Build Coastguard Worker fAzimuth = kStartAzimuth + TimeUtils::Scaled(1e-9 * nanos, 360.0f/kDesiredDurationSecs, 360.0f); 175*c8dee2aaSAndroid Build Coastguard Worker return true; 176*c8dee2aaSAndroid Build Coastguard Worker } 177*c8dee2aaSAndroid Build Coastguard Worker 178*c8dee2aaSAndroid Build Coastguard Worker private: 179*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr int kStartAzimuth = 225; 180*c8dee2aaSAndroid Build Coastguard Worker 181*c8dee2aaSAndroid Build Coastguard Worker SkBitmap fBitmap; 182*c8dee2aaSAndroid Build Coastguard Worker SkScalar fAzimuth; 183*c8dee2aaSAndroid Build Coastguard Worker 184*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = GM; 185*c8dee2aaSAndroid Build Coastguard Worker }; 186*c8dee2aaSAndroid Build Coastguard Worker 187*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////// 188*c8dee2aaSAndroid Build Coastguard Worker 189*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new ImageLightingGM;) 190*c8dee2aaSAndroid Build Coastguard Worker } // namespace skiagm 191