blob: d61e25e023482210060a90679deb0eaeae4e43e8 [file] [log] [blame]
sugoi@google.come3b4c502013-04-05 13:47:09 +00001/*
2 * Copyright 2013 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/SkCanvas.h"
10#include "include/core/SkColor.h"
11#include "include/core/SkMatrix.h"
12#include "include/core/SkPaint.h"
13#include "include/core/SkRect.h"
14#include "include/core/SkRefCnt.h"
15#include "include/core/SkScalar.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "include/core/SkShader.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040017#include "include/core/SkSize.h"
18#include "include/core/SkString.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "include/effects/SkPerlinNoiseShader.h"
Florin Malita14d54c22017-05-18 11:52:59 -040020
Ben Wagner7fde8e12019-05-01 17:28:53 -040021#include <utility>
22
Florin Malita14d54c22017-05-18 11:52:59 -040023namespace {
24
25enum class Type {
26 kFractalNoise,
27 kTurbulence,
Brian Salomon756995b2021-01-06 19:30:00 -050028 kImproved,
Florin Malita14d54c22017-05-18 11:52:59 -040029};
30
reed@google.coma501a642014-05-12 17:18:45 +000031class PerlinNoiseGM : public skiagm::GM {
Hal Canarybd865e22019-07-18 11:51:19 -040032 SkISize fSize = {80, 80};
sugoi@google.come3b4c502013-04-05 13:47:09 +000033
Hal Canarybd865e22019-07-18 11:51:19 -040034 void onOnceBeforeDraw() override { this->setBGColor(0xFF000000); }
sugoi@google.come3b4c502013-04-05 13:47:09 +000035
Hal Canarybd865e22019-07-18 11:51:19 -040036 SkString onShortName() override { return SkString("perlinnoise"); }
37
Brian Salomon756995b2021-01-06 19:30:00 -050038 SkISize onISize() override { return {200, 600}; }
sugoi@google.come3b4c502013-04-05 13:47:09 +000039
senorblancoce6a3542014-06-12 11:24:19 -070040 void drawRect(SkCanvas* canvas, int x, int y, const SkPaint& paint, const SkISize& size) {
sugoi@google.come3b4c502013-04-05 13:47:09 +000041 canvas->save();
senorblancoce6a3542014-06-12 11:24:19 -070042 canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
43 SkRect r = SkRect::MakeWH(SkIntToScalar(size.width()),
44 SkIntToScalar(size.height()));
sugoi@google.come3b4c502013-04-05 13:47:09 +000045 canvas->drawRect(r, paint);
46 canvas->restore();
47 }
48
Florin Malita14d54c22017-05-18 11:52:59 -040049 void test(SkCanvas* canvas, int x, int y, Type type,
Brian Salomon756995b2021-01-06 19:30:00 -050050 float baseFrequencyX, float baseFrequencyY, int numOctaves, float seedOrZ,
sugoi@google.com4775cba2013-04-17 13:46:56 +000051 bool stitchTiles) {
senorblancoce6a3542014-06-12 11:24:19 -070052 SkISize tileSize = SkISize::Make(fSize.width() / 2, fSize.height() / 2);
Brian Salomon756995b2021-01-06 19:30:00 -050053 sk_sp<SkShader> shader;
54 switch (type) {
55 case Type::kFractalNoise:
56 shader = SkPerlinNoiseShader::MakeFractalNoise(baseFrequencyX,
57 baseFrequencyY,
58 numOctaves,
59 seedOrZ,
60 stitchTiles ? &tileSize : nullptr);
61 break;
62 case Type::kTurbulence:
63 shader = SkPerlinNoiseShader::MakeTurbulence(baseFrequencyX,
64 baseFrequencyY,
65 numOctaves,
66 seedOrZ,
67 stitchTiles ? &tileSize : nullptr);
68 break;
69 case Type::kImproved:
70 SkASSERT(!stitchTiles);
71 shader = SkPerlinNoiseShader::MakeImprovedNoise(baseFrequencyX,
72 baseFrequencyY,
73 numOctaves,
74 seedOrZ);
75 break;
76 }
sugoi@google.come3b4c502013-04-05 13:47:09 +000077 SkPaint paint;
reedfe630452016-03-25 09:08:00 -070078 paint.setShader(std::move(shader));
senorblancoce6a3542014-06-12 11:24:19 -070079 if (stitchTiles) {
80 drawRect(canvas, x, y, paint, tileSize);
81 x += tileSize.width();
82 drawRect(canvas, x, y, paint, tileSize);
83 y += tileSize.width();
84 drawRect(canvas, x, y, paint, tileSize);
85 x -= tileSize.width();
86 drawRect(canvas, x, y, paint, tileSize);
87 } else {
88 drawRect(canvas, x, y, paint, fSize);
89 }
sugoi@google.come3b4c502013-04-05 13:47:09 +000090 }
91
Hal Canarybd865e22019-07-18 11:51:19 -040092 void onDraw(SkCanvas* canvas) override {
senorblanco16b254a2015-04-09 11:13:24 -070093 canvas->clear(SK_ColorBLACK);
Florin Malita14d54c22017-05-18 11:52:59 -040094 test(canvas, 0, 0, Type::kFractalNoise,
commit-bot@chromium.orgc2a0ea62013-11-06 10:08:38 +000095 0.1f, 0.1f, 0, 0, false);
Florin Malita14d54c22017-05-18 11:52:59 -040096 test(canvas, 100, 0, Type::kTurbulence,
commit-bot@chromium.orgc2a0ea62013-11-06 10:08:38 +000097 0.1f, 0.1f, 0, 0, false);
skia.committer@gmail.comcff02432013-04-06 07:01:10 +000098
Florin Malita14d54c22017-05-18 11:52:59 -040099 test(canvas, 0, 100, Type::kFractalNoise,
sugoi@google.come3b4c502013-04-05 13:47:09 +0000100 0.1f, 0.1f, 2, 0, false);
Florin Malita14d54c22017-05-18 11:52:59 -0400101 test(canvas, 100, 100, Type::kFractalNoise,
senorblancoce6a3542014-06-12 11:24:19 -0700102 0.05f, 0.1f, 1, 0, true);
sugoi@google.come3b4c502013-04-05 13:47:09 +0000103
Florin Malita14d54c22017-05-18 11:52:59 -0400104 test(canvas, 0, 200, Type::kTurbulence,
senorblancoce6a3542014-06-12 11:24:19 -0700105 0.1f, 0.1f, 1, 0, true);
Florin Malita14d54c22017-05-18 11:52:59 -0400106 test(canvas, 100, 200, Type::kTurbulence,
sugoi@google.come3b4c502013-04-05 13:47:09 +0000107 0.2f, 0.4f, 5, 0, false);
sugoi@google.come3b4c502013-04-05 13:47:09 +0000108
Florin Malita14d54c22017-05-18 11:52:59 -0400109 test(canvas, 0, 300, Type::kFractalNoise,
sugoi@google.come3b4c502013-04-05 13:47:09 +0000110 0.1f, 0.1f, 3, 1, false);
Florin Malita14d54c22017-05-18 11:52:59 -0400111 test(canvas, 100, 300, Type::kFractalNoise,
sugoi@google.come3b4c502013-04-05 13:47:09 +0000112 0.1f, 0.1f, 3, 4, false);
sugoi@google.come3b4c502013-04-05 13:47:09 +0000113
Brian Salomon756995b2021-01-06 19:30:00 -0500114 test(canvas, 0, 400, Type::kImproved,
115 0.0125f, 0.0125f, 4, 0, false);
116 test(canvas, 100, 400, Type::kImproved,
117 0.125f, 0.0075f, 2, 0, false);
118
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000119 canvas->scale(0.75f, 1.0f);
sugoi@google.come3b4c502013-04-05 13:47:09 +0000120
Brian Salomon756995b2021-01-06 19:30:00 -0500121 test(canvas, 0, 500, Type::kFractalNoise,
sugoi@google.come3b4c502013-04-05 13:47:09 +0000122 0.1f, 0.1f, 2, 0, false);
Brian Salomon756995b2021-01-06 19:30:00 -0500123 test(canvas, 100, 500, Type::kFractalNoise,
senorblancoce6a3542014-06-12 11:24:19 -0700124 0.1f, 0.05f, 1, 0, true);
sugoi@google.come3b4c502013-04-05 13:47:09 +0000125 }
126
127private:
John Stiles7571f9e2020-09-02 22:42:33 -0400128 using INHERITED = GM;
sugoi@google.come3b4c502013-04-05 13:47:09 +0000129};
130
reed@google.coma501a642014-05-12 17:18:45 +0000131class PerlinNoiseGM2 : public skiagm::GM {
Hal Canarybd865e22019-07-18 11:51:19 -0400132 SkISize fSize = {80, 80};
skia.committer@gmail.come92c68f72014-05-13 03:06:05 +0000133
Hal Canarybd865e22019-07-18 11:51:19 -0400134 SkString onShortName() override { return SkString("perlinnoise_localmatrix"); }
skia.committer@gmail.come92c68f72014-05-13 03:06:05 +0000135
Hal Canarybd865e22019-07-18 11:51:19 -0400136 SkISize onISize() override { return {640, 480}; }
skia.committer@gmail.come92c68f72014-05-13 03:06:05 +0000137
Florin Malita14d54c22017-05-18 11:52:59 -0400138 void install(SkPaint* paint, Type type,
reed@google.coma501a642014-05-12 17:18:45 +0000139 float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed,
140 bool stitchTiles) {
Florin Malita14d54c22017-05-18 11:52:59 -0400141 sk_sp<SkShader> shader = (type == Type::kFractalNoise) ?
reedfe630452016-03-25 09:08:00 -0700142 SkPerlinNoiseShader::MakeFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves,
143 seed, stitchTiles ? &fSize : nullptr) :
144 SkPerlinNoiseShader::MakeTurbulence(baseFrequencyX, baseFrequencyY, numOctaves,
145 seed, stitchTiles ? &fSize : nullptr);
146 paint->setShader(std::move(shader));
reed@google.coma501a642014-05-12 17:18:45 +0000147 }
skia.committer@gmail.come92c68f72014-05-13 03:06:05 +0000148
Hal Canarybd865e22019-07-18 11:51:19 -0400149 void onDraw(SkCanvas* canvas) override {
reed@google.coma501a642014-05-12 17:18:45 +0000150 canvas->translate(10, 10);
151
152 SkPaint paint;
Robert Phillipsbee27322018-01-23 09:58:18 -0500153 this->install(&paint, Type::kFractalNoise, 0.1f, 0.1f, 2, 0, false);
reed@google.coma501a642014-05-12 17:18:45 +0000154
155 const SkScalar w = SkIntToScalar(fSize.width());
156 const SkScalar h = SkIntToScalar(fSize.height());
157
158 SkRect r = SkRect::MakeWH(w, h);
159 canvas->drawRect(r, paint);
160
161 canvas->save();
162 canvas->translate(w * 5/4, 0);
163 canvas->drawRect(r, paint);
164 canvas->restore();
165
166 canvas->save();
167 canvas->translate(0, h + 10);
168 canvas->scale(2, 2);
169 canvas->drawRect(r, paint);
170 canvas->restore();
skia.committer@gmail.come92c68f72014-05-13 03:06:05 +0000171
reed@google.coma501a642014-05-12 17:18:45 +0000172 canvas->save();
173 canvas->translate(w + 100, h + 10);
174 canvas->scale(2, 2);
175 canvas->drawRect(r, paint);
176 canvas->restore();
177
178 // The next row should draw the same as the previous, even though we are using a local
179 // matrix instead of the canvas.
180
181 canvas->translate(0, h * 2 + 10);
182
183 SkMatrix lm;
184 lm.setScale(2, 2);
reed150835e2016-03-10 06:36:49 -0800185 paint.setShader(paint.getShader()->makeWithLocalMatrix(lm));
reed@google.coma501a642014-05-12 17:18:45 +0000186 r.fRight += r.width();
187 r.fBottom += r.height();
188
189 canvas->save();
190 canvas->translate(0, h + 10);
191 canvas->drawRect(r, paint);
192 canvas->restore();
skia.committer@gmail.come92c68f72014-05-13 03:06:05 +0000193
reed@google.coma501a642014-05-12 17:18:45 +0000194 canvas->save();
195 canvas->translate(w + 100, h + 10);
196 canvas->drawRect(r, paint);
197 canvas->restore();
198 }
reed@google.coma501a642014-05-12 17:18:45 +0000199};
200
Hal Canarybd865e22019-07-18 11:51:19 -0400201} // namespace
sugoi@google.come3b4c502013-04-05 13:47:09 +0000202
reed@google.coma501a642014-05-12 17:18:45 +0000203DEF_GM( return new PerlinNoiseGM; )
204DEF_GM( return new PerlinNoiseGM2; )