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