blob: c2bded71ac6677cd9cc72922d448ad1285b8f455 [file] [log] [blame]
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +00001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -04009#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"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkPoint3.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040015#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"
Michael Ludwig898bbfa2019-08-02 15:21:23 -040020#include "include/effects/SkImageFilters.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "tools/ToolUtils.h"
Hal Canary41248072019-07-11 16:32:53 -040022#include "tools/timer/TimeUtils.h"
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000023
Michael Ludwigf5774272021-01-21 18:43:58 -050024#define WIDTH 660
senorblancod0d37ca2015-04-02 04:54:56 -070025#define HEIGHT 660
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000026
27namespace skiagm {
28
29class ImageLightingGM : public GM {
30public:
robertphillips651bb5f2016-04-08 13:35:14 -070031 ImageLightingGM()
32 : fAzimuth(SkIntToScalar(kStartAzimuth)) {
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000033 this->setBGColor(0xFF000000);
34 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000035
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000036protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000037
mtklein36352bf2015-03-25 18:17:31 -070038 SkString onShortName() override {
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000039 return SkString("lighting");
40 }
41
mtklein36352bf2015-03-25 18:17:31 -070042 SkISize onISize() override {
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +000043 return SkISize::Make(WIDTH, HEIGHT);
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000044 }
45
junov@chromium.orgff06af22013-01-14 16:27:50 +000046 void drawClippedBitmap(SkCanvas* canvas, const SkPaint& paint, int x, int y) {
47 canvas->save();
senorblanco@chromium.orgfbaea532013-08-27 21:37:01 +000048 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);
junov@chromium.orgff06af22013-01-14 16:27:50 +000052 canvas->restore();
53 }
54
robertphillips943a4622015-09-03 13:32:33 -070055 void onOnceBeforeDraw() override {
Mike Kleinea3f0142019-03-20 11:12:10 -050056 fBitmap = ToolUtils::create_string_bitmap(100, 100, 0xFFFFFFFF, 20, 70, 96, "e");
robertphillips943a4622015-09-03 13:32:33 -070057 }
58
mtklein36352bf2015-03-25 18:17:31 -070059 void onDraw(SkCanvas* canvas) override {
Mike Kleind46dce32018-08-16 10:17:03 -040060 canvas->clear(0xFF101010);
senorblanco@chromium.org7b734e02012-10-29 19:47:06 +000061 SkPaint checkPaint;
Mike Kleind46dce32018-08-16 10:17:03 -040062 checkPaint.setColor(0xFF202020);
senorblanco@chromium.org7b734e02012-10-29 19:47:06 +000063 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 }
Brian Osman4428f2c2019-04-02 10:59:28 -040072 SkScalar sinAzimuth = SkScalarSin(SkDegreesToRadians(fAzimuth)),
73 cosAzimuth = SkScalarCos(SkDegreesToRadians(fAzimuth));
robertphillips651bb5f2016-04-08 13:35:14 -070074
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));
Michael Ludwigf5774272021-01-21 18:43:58 -050079 SkScalar spotExponent1 = SK_Scalar1;
80 SkScalar spotExponent10 = SkIntToScalar(10);
81 SkScalar cutoffAngleSmall = SkIntToScalar(15);
82 SkScalar cutoffAngleNone = SkIntToScalar(180);
robertphillips651bb5f2016-04-08 13:35:14 -070083
84 SkPoint3 pointLocation = SkPoint3::Make(spotTarget.fX + 50 * cosAzimuth,
85 spotTarget.fY + 50 * sinAzimuth,
86 SkIntToScalar(10));
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000087 SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5));
robertphillips651bb5f2016-04-08 13:35:14 -070088
Mike Reeddf85c382017-02-14 10:59:19 -050089 SkPoint3 distantDirection = SkPoint3::Make(cosAzimuth * SkScalarCos(elevationRad),
90 sinAzimuth * SkScalarCos(elevationRad),
robertphillips3d32d762015-07-13 13:16:44 -070091 SkScalarSin(elevationRad));
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000092 SkScalar kd = SkIntToScalar(2);
93 SkScalar ks = SkIntToScalar(1);
94 SkScalar shininess = SkIntToScalar(8);
95 SkScalar surfaceScale = SkIntToScalar(1);
Michael Ludwigf5774272021-01-21 18:43:58 -050096 SkScalar surfaceScaleSmall = 0.1f;
97 SkColor greenYellow = SkColorSetARGB(255, 173, 255, 47);
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000098 SkPaint paint;
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +000099
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400100 SkIRect cropRect = SkIRect::MakeXYWH(20, 10, 60, 65);
101 SkIRect fullSizeCropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
102 sk_sp<SkImageFilter> noopCropped(SkImageFilters::Offset(0, 0, nullptr, &cropRect));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000103
104 int y = 0;
senorblancod0d37ca2015-04-02 04:54:56 -0700105 for (int i = 0; i < 3; i++) {
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400106 const SkIRect* cr = (i == 1) ? &cropRect : (i == 2) ? &fullSizeCropRect : nullptr;
robertphillips12fa47d2016-04-08 16:28:09 -0700107 sk_sp<SkImageFilter> input = (i == 2) ? noopCropped : nullptr;
Michael Ludwigf5774272021-01-21 18:43:58 -0500108 // Basic point, distant and spot lights with diffuse lighting
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400109 paint.setImageFilter(SkImageFilters::PointLitDiffuse(
Michael Ludwigf5774272021-01-21 18:43:58 -0500110 pointLocation, SK_ColorWHITE, surfaceScale, kd, input, cr));
robertphillips12fa47d2016-04-08 16:28:09 -0700111 drawClippedBitmap(canvas, paint, 0, y);
112
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400113 paint.setImageFilter(SkImageFilters::DistantLitDiffuse(
Michael Ludwigf5774272021-01-21 18:43:58 -0500114 distantDirection, SK_ColorWHITE, surfaceScale, kd, input, cr));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000115 drawClippedBitmap(canvas, paint, 110, y);
senorblanco@chromium.orgfbaea532013-08-27 21:37:01 +0000116
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400117 paint.setImageFilter(SkImageFilters::SpotLitDiffuse(
Michael Ludwigf5774272021-01-21 18:43:58 -0500118 spotLocation, spotTarget, spotExponent1, cutoffAngleSmall, SK_ColorWHITE,
119 surfaceScale, kd, input, cr));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000120 drawClippedBitmap(canvas, paint, 220, y);
121
Michael Ludwigf5774272021-01-21 18:43:58 -0500122 // Spot light with no angle cutoff
123 paint.setImageFilter(SkImageFilters::SpotLitDiffuse(
124 spotLocation, spotTarget, spotExponent10, cutoffAngleNone, SK_ColorWHITE,
125 surfaceScale, kd, input, cr));
126 drawClippedBitmap(canvas, paint, 330, y);
127
128 // Spot light with falloff exponent
129 paint.setImageFilter(SkImageFilters::SpotLitDiffuse(
130 spotLocation, spotTarget, spotExponent1, cutoffAngleNone, SK_ColorWHITE,
131 surfaceScaleSmall, kd, input, cr));
132 drawClippedBitmap(canvas, paint, 440, y);
133
134 // Large constant to show oversaturation
135 paint.setImageFilter(SkImageFilters::DistantLitDiffuse(
136 distantDirection, greenYellow, surfaceScale, 4.f * kd, input, cr));
137 drawClippedBitmap(canvas, paint, 550, y);
138
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000139 y += 110;
senorblanco@chromium.orgfbaea532013-08-27 21:37:01 +0000140
Michael Ludwigf5774272021-01-21 18:43:58 -0500141 // Basic point, distant and spot lights with specular lighting
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400142 paint.setImageFilter(SkImageFilters::PointLitSpecular(
Michael Ludwigf5774272021-01-21 18:43:58 -0500143 pointLocation, SK_ColorWHITE, surfaceScale, ks, shininess, input, cr));
robertphillips12fa47d2016-04-08 16:28:09 -0700144 drawClippedBitmap(canvas, paint, 0, y);
145
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400146 paint.setImageFilter(SkImageFilters::DistantLitSpecular(
Michael Ludwigf5774272021-01-21 18:43:58 -0500147 distantDirection, SK_ColorWHITE, surfaceScale, ks, shininess, input, cr));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000148 drawClippedBitmap(canvas, paint, 110, y);
senorblanco@chromium.orgfbaea532013-08-27 21:37:01 +0000149
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400150 paint.setImageFilter(SkImageFilters::SpotLitSpecular(
Michael Ludwigf5774272021-01-21 18:43:58 -0500151 spotLocation, spotTarget, spotExponent1, cutoffAngleSmall, SK_ColorWHITE,
152 surfaceScale, ks, shininess, input, cr));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000153 drawClippedBitmap(canvas, paint, 220, y);
senorblanco@chromium.orgfbaea532013-08-27 21:37:01 +0000154
Michael Ludwigf5774272021-01-21 18:43:58 -0500155 // Spot light with no angle cutoff
156 paint.setImageFilter(SkImageFilters::SpotLitSpecular(
157 spotLocation, spotTarget, spotExponent10, cutoffAngleNone, SK_ColorWHITE,
158 surfaceScale, ks, shininess, input, cr));
159 drawClippedBitmap(canvas, paint, 330, y);
160
161 // Spot light with falloff exponent
162 paint.setImageFilter(SkImageFilters::SpotLitSpecular(
163 spotLocation, spotTarget, spotExponent1, cutoffAngleNone, SK_ColorWHITE,
164 surfaceScaleSmall, ks, shininess, input, cr));
165 drawClippedBitmap(canvas, paint, 440, y);
166
167 // Large constant to show oversaturation
168 paint.setImageFilter(SkImageFilters::DistantLitSpecular(
169 distantDirection, greenYellow, surfaceScale, 4.f * ks, shininess, input, cr));
170 drawClippedBitmap(canvas, paint, 550, y);
171
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000172 y += 110;
173 }
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +0000174 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000175
Hal Canary41248072019-07-11 16:32:53 -0400176 bool onAnimate(double nanos) override {
mtkleindbfd7ab2016-09-01 11:24:54 -0700177 constexpr SkScalar kDesiredDurationSecs = 15.0f;
robertphillips651bb5f2016-04-08 13:35:14 -0700178
Hal Canary41248072019-07-11 16:32:53 -0400179 fAzimuth = kStartAzimuth + TimeUtils::Scaled(1e-9 * nanos, 360.0f/kDesiredDurationSecs, 360.0f);
robertphillips651bb5f2016-04-08 13:35:14 -0700180 return true;
181 }
182
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +0000183private:
mtkleindbfd7ab2016-09-01 11:24:54 -0700184 static constexpr int kStartAzimuth = 225;
robertphillips651bb5f2016-04-08 13:35:14 -0700185
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +0000186 SkBitmap fBitmap;
robertphillips651bb5f2016-04-08 13:35:14 -0700187 SkScalar fAzimuth;
robertphillips943a4622015-09-03 13:32:33 -0700188
John Stiles7571f9e2020-09-02 22:42:33 -0400189 using INHERITED = GM;
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +0000190};
191
192//////////////////////////////////////////////////////////////////////////////
193
halcanary385fe4d2015-08-26 13:07:48 -0700194DEF_GM(return new ImageLightingGM;)
John Stilesa6841be2020-08-06 14:11:56 -0400195} // namespace skiagm