blob: 268842aaaf1117fb9fca9f927bbf6ba2654ce30c [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));
Mike Reed607a3822021-01-24 19:49:21 -050049 canvas->clipIRect(fBitmap.bounds());
50 canvas->drawImage(fBitmap.asImage(), 0, 0, SkSamplingOptions(), &paint);
junov@chromium.orgff06af22013-01-14 16:27:50 +000051 canvas->restore();
52 }
53
robertphillips943a4622015-09-03 13:32:33 -070054 void onOnceBeforeDraw() override {
Mike Kleinea3f0142019-03-20 11:12:10 -050055 fBitmap = ToolUtils::create_string_bitmap(100, 100, 0xFFFFFFFF, 20, 70, 96, "e");
robertphillips943a4622015-09-03 13:32:33 -070056 }
57
mtklein36352bf2015-03-25 18:17:31 -070058 void onDraw(SkCanvas* canvas) override {
Mike Kleind46dce32018-08-16 10:17:03 -040059 canvas->clear(0xFF101010);
senorblanco@chromium.org7b734e02012-10-29 19:47:06 +000060 SkPaint checkPaint;
Mike Kleind46dce32018-08-16 10:17:03 -040061 checkPaint.setColor(0xFF202020);
senorblanco@chromium.org7b734e02012-10-29 19:47:06 +000062 for (int y = 0; y < HEIGHT; y += 16) {
63 for (int x = 0; x < WIDTH; x += 16) {
64 canvas->save();
65 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
66 canvas->drawRect(SkRect::MakeXYWH(8, 0, 8, 8), checkPaint);
67 canvas->drawRect(SkRect::MakeXYWH(0, 8, 8, 8), checkPaint);
68 canvas->restore();
69 }
70 }
Brian Osman4428f2c2019-04-02 10:59:28 -040071 SkScalar sinAzimuth = SkScalarSin(SkDegreesToRadians(fAzimuth)),
72 cosAzimuth = SkScalarCos(SkDegreesToRadians(fAzimuth));
robertphillips651bb5f2016-04-08 13:35:14 -070073
74 SkPoint3 spotTarget = SkPoint3::Make(SkIntToScalar(40), SkIntToScalar(40), 0);
75 SkPoint3 spotLocation = SkPoint3::Make(spotTarget.fX + 70.7214f * cosAzimuth,
76 spotTarget.fY + 70.7214f * sinAzimuth,
77 spotTarget.fZ + SkIntToScalar(20));
Michael Ludwigf5774272021-01-21 18:43:58 -050078 SkScalar spotExponent1 = SK_Scalar1;
79 SkScalar spotExponent10 = SkIntToScalar(10);
80 SkScalar cutoffAngleSmall = SkIntToScalar(15);
81 SkScalar cutoffAngleNone = SkIntToScalar(180);
robertphillips651bb5f2016-04-08 13:35:14 -070082
83 SkPoint3 pointLocation = SkPoint3::Make(spotTarget.fX + 50 * cosAzimuth,
84 spotTarget.fY + 50 * sinAzimuth,
85 SkIntToScalar(10));
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000086 SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5));
robertphillips651bb5f2016-04-08 13:35:14 -070087
Mike Reeddf85c382017-02-14 10:59:19 -050088 SkPoint3 distantDirection = SkPoint3::Make(cosAzimuth * SkScalarCos(elevationRad),
89 sinAzimuth * SkScalarCos(elevationRad),
robertphillips3d32d762015-07-13 13:16:44 -070090 SkScalarSin(elevationRad));
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000091 SkScalar kd = SkIntToScalar(2);
92 SkScalar ks = SkIntToScalar(1);
93 SkScalar shininess = SkIntToScalar(8);
94 SkScalar surfaceScale = SkIntToScalar(1);
Michael Ludwigf5774272021-01-21 18:43:58 -050095 SkScalar surfaceScaleSmall = 0.1f;
96 SkColor greenYellow = SkColorSetARGB(255, 173, 255, 47);
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +000097 SkPaint paint;
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +000098
Michael Ludwig898bbfa2019-08-02 15:21:23 -040099 SkIRect cropRect = SkIRect::MakeXYWH(20, 10, 60, 65);
100 SkIRect fullSizeCropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
101 sk_sp<SkImageFilter> noopCropped(SkImageFilters::Offset(0, 0, nullptr, &cropRect));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000102
103 int y = 0;
senorblancod0d37ca2015-04-02 04:54:56 -0700104 for (int i = 0; i < 3; i++) {
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400105 const SkIRect* cr = (i == 1) ? &cropRect : (i == 2) ? &fullSizeCropRect : nullptr;
robertphillips12fa47d2016-04-08 16:28:09 -0700106 sk_sp<SkImageFilter> input = (i == 2) ? noopCropped : nullptr;
Michael Ludwigf5774272021-01-21 18:43:58 -0500107 // Basic point, distant and spot lights with diffuse lighting
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400108 paint.setImageFilter(SkImageFilters::PointLitDiffuse(
Michael Ludwigf5774272021-01-21 18:43:58 -0500109 pointLocation, SK_ColorWHITE, surfaceScale, kd, input, cr));
robertphillips12fa47d2016-04-08 16:28:09 -0700110 drawClippedBitmap(canvas, paint, 0, y);
111
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400112 paint.setImageFilter(SkImageFilters::DistantLitDiffuse(
Michael Ludwigf5774272021-01-21 18:43:58 -0500113 distantDirection, SK_ColorWHITE, surfaceScale, kd, input, cr));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000114 drawClippedBitmap(canvas, paint, 110, y);
senorblanco@chromium.orgfbaea532013-08-27 21:37:01 +0000115
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400116 paint.setImageFilter(SkImageFilters::SpotLitDiffuse(
Michael Ludwigf5774272021-01-21 18:43:58 -0500117 spotLocation, spotTarget, spotExponent1, cutoffAngleSmall, SK_ColorWHITE,
118 surfaceScale, kd, input, cr));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000119 drawClippedBitmap(canvas, paint, 220, y);
120
Michael Ludwigf5774272021-01-21 18:43:58 -0500121 // Spot light with no angle cutoff
122 paint.setImageFilter(SkImageFilters::SpotLitDiffuse(
123 spotLocation, spotTarget, spotExponent10, cutoffAngleNone, SK_ColorWHITE,
124 surfaceScale, kd, input, cr));
125 drawClippedBitmap(canvas, paint, 330, y);
126
127 // Spot light with falloff exponent
128 paint.setImageFilter(SkImageFilters::SpotLitDiffuse(
129 spotLocation, spotTarget, spotExponent1, cutoffAngleNone, SK_ColorWHITE,
130 surfaceScaleSmall, kd, input, cr));
131 drawClippedBitmap(canvas, paint, 440, y);
132
133 // Large constant to show oversaturation
134 paint.setImageFilter(SkImageFilters::DistantLitDiffuse(
135 distantDirection, greenYellow, surfaceScale, 4.f * kd, input, cr));
136 drawClippedBitmap(canvas, paint, 550, y);
137
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000138 y += 110;
senorblanco@chromium.orgfbaea532013-08-27 21:37:01 +0000139
Michael Ludwigf5774272021-01-21 18:43:58 -0500140 // Basic point, distant and spot lights with specular lighting
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400141 paint.setImageFilter(SkImageFilters::PointLitSpecular(
Michael Ludwigf5774272021-01-21 18:43:58 -0500142 pointLocation, SK_ColorWHITE, surfaceScale, ks, shininess, input, cr));
robertphillips12fa47d2016-04-08 16:28:09 -0700143 drawClippedBitmap(canvas, paint, 0, y);
144
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400145 paint.setImageFilter(SkImageFilters::DistantLitSpecular(
Michael Ludwigf5774272021-01-21 18:43:58 -0500146 distantDirection, SK_ColorWHITE, surfaceScale, ks, shininess, input, cr));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000147 drawClippedBitmap(canvas, paint, 110, y);
senorblanco@chromium.orgfbaea532013-08-27 21:37:01 +0000148
Michael Ludwig898bbfa2019-08-02 15:21:23 -0400149 paint.setImageFilter(SkImageFilters::SpotLitSpecular(
Michael Ludwigf5774272021-01-21 18:43:58 -0500150 spotLocation, spotTarget, spotExponent1, cutoffAngleSmall, SK_ColorWHITE,
151 surfaceScale, ks, shininess, input, cr));
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000152 drawClippedBitmap(canvas, paint, 220, y);
senorblanco@chromium.orgfbaea532013-08-27 21:37:01 +0000153
Michael Ludwigf5774272021-01-21 18:43:58 -0500154 // Spot light with no angle cutoff
155 paint.setImageFilter(SkImageFilters::SpotLitSpecular(
156 spotLocation, spotTarget, spotExponent10, cutoffAngleNone, SK_ColorWHITE,
157 surfaceScale, ks, shininess, input, cr));
158 drawClippedBitmap(canvas, paint, 330, y);
159
160 // Spot light with falloff exponent
161 paint.setImageFilter(SkImageFilters::SpotLitSpecular(
162 spotLocation, spotTarget, spotExponent1, cutoffAngleNone, SK_ColorWHITE,
163 surfaceScaleSmall, ks, shininess, input, cr));
164 drawClippedBitmap(canvas, paint, 440, y);
165
166 // Large constant to show oversaturation
167 paint.setImageFilter(SkImageFilters::DistantLitSpecular(
168 distantDirection, greenYellow, surfaceScale, 4.f * ks, shininess, input, cr));
169 drawClippedBitmap(canvas, paint, 550, y);
170
senorblanco@chromium.org4e16bb22013-07-26 00:10:07 +0000171 y += 110;
172 }
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +0000173 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000174
Hal Canary41248072019-07-11 16:32:53 -0400175 bool onAnimate(double nanos) override {
mtkleindbfd7ab2016-09-01 11:24:54 -0700176 constexpr SkScalar kDesiredDurationSecs = 15.0f;
robertphillips651bb5f2016-04-08 13:35:14 -0700177
Hal Canary41248072019-07-11 16:32:53 -0400178 fAzimuth = kStartAzimuth + TimeUtils::Scaled(1e-9 * nanos, 360.0f/kDesiredDurationSecs, 360.0f);
robertphillips651bb5f2016-04-08 13:35:14 -0700179 return true;
180 }
181
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +0000182private:
mtkleindbfd7ab2016-09-01 11:24:54 -0700183 static constexpr int kStartAzimuth = 225;
robertphillips651bb5f2016-04-08 13:35:14 -0700184
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +0000185 SkBitmap fBitmap;
robertphillips651bb5f2016-04-08 13:35:14 -0700186 SkScalar fAzimuth;
robertphillips943a4622015-09-03 13:32:33 -0700187
John Stiles7571f9e2020-09-02 22:42:33 -0400188 using INHERITED = GM;
senorblanco@chromium.orgf49b4292012-06-22 21:01:23 +0000189};
190
191//////////////////////////////////////////////////////////////////////////////
192
halcanary385fe4d2015-08-26 13:07:48 -0700193DEF_GM(return new ImageLightingGM;)
John Stilesa6841be2020-08-06 14:11:56 -0400194} // namespace skiagm