• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
8 #include "gm.h"
9 #include "SkPerlinNoiseShader.h"
10 #include "SkShader.h"
11 
12 namespace {
13 
14 enum class Type {
15     kFractalNoise,
16     kTurbulence,
17 };
18 
19 } // anonymous ns
20 
21 class PerlinNoiseGM : public skiagm::GM {
22 public:
PerlinNoiseGM()23     PerlinNoiseGM() {
24         this->setBGColor(0xFF000000);
25         fSize = SkISize::Make(80, 80);
26     }
27 
28 protected:
onShortName()29     virtual SkString onShortName() {
30         return SkString("perlinnoise");
31     }
32 
onISize()33     virtual SkISize onISize() {
34         return SkISize::Make(200, 500);
35     }
36 
drawRect(SkCanvas * canvas,int x,int y,const SkPaint & paint,const SkISize & size)37     void drawRect(SkCanvas* canvas, int x, int y, const SkPaint& paint, const SkISize& size) {
38         canvas->save();
39         canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
40         SkRect r = SkRect::MakeWH(SkIntToScalar(size.width()),
41                                   SkIntToScalar(size.height()));
42         canvas->drawRect(r, paint);
43         canvas->restore();
44     }
45 
test(SkCanvas * canvas,int x,int y,Type type,float baseFrequencyX,float baseFrequencyY,int numOctaves,float seed,bool stitchTiles)46     void test(SkCanvas* canvas, int x, int y, Type type,
47               float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed,
48               bool stitchTiles) {
49         SkISize tileSize = SkISize::Make(fSize.width() / 2, fSize.height() / 2);
50         sk_sp<SkShader> shader = (type == Type::kFractalNoise) ?
51             SkPerlinNoiseShader::MakeFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves,
52                                                   seed, stitchTiles ? &tileSize : nullptr) :
53             SkPerlinNoiseShader::MakeTurbulence(baseFrequencyX, baseFrequencyY, numOctaves,
54                                                 seed, stitchTiles ? &tileSize : nullptr);
55         SkPaint paint;
56         paint.setShader(std::move(shader));
57         if (stitchTiles) {
58             drawRect(canvas, x, y, paint, tileSize);
59             x += tileSize.width();
60             drawRect(canvas, x, y, paint, tileSize);
61             y += tileSize.width();
62             drawRect(canvas, x, y, paint, tileSize);
63             x -= tileSize.width();
64             drawRect(canvas, x, y, paint, tileSize);
65         } else {
66             drawRect(canvas, x, y, paint, fSize);
67         }
68     }
69 
onDraw(SkCanvas * canvas)70     virtual void onDraw(SkCanvas* canvas) {
71         canvas->clear(SK_ColorBLACK);
72         test(canvas,   0,   0, Type::kFractalNoise,
73              0.1f, 0.1f, 0, 0, false);
74         test(canvas, 100,   0, Type::kTurbulence,
75              0.1f, 0.1f, 0, 0, false);
76 
77         test(canvas,   0, 100, Type::kFractalNoise,
78              0.1f, 0.1f, 2, 0, false);
79         test(canvas, 100, 100, Type::kFractalNoise,
80              0.05f, 0.1f, 1, 0, true);
81 
82         test(canvas,   0, 200, Type::kTurbulence,
83              0.1f, 0.1f, 1, 0, true);
84         test(canvas, 100, 200, Type::kTurbulence,
85              0.2f, 0.4f, 5, 0, false);
86 
87         test(canvas,   0, 300, Type::kFractalNoise,
88              0.1f, 0.1f, 3, 1, false);
89         test(canvas, 100, 300, Type::kFractalNoise,
90              0.1f, 0.1f, 3, 4, false);
91 
92         canvas->scale(0.75f, 1.0f);
93 
94         test(canvas,   0, 400, Type::kFractalNoise,
95              0.1f, 0.1f, 2, 0, false);
96         test(canvas, 100, 400, Type::kFractalNoise,
97              0.1f, 0.05f, 1, 0, true);
98     }
99 
100 private:
101     typedef GM INHERITED;
102     SkISize fSize;
103 };
104 
105 class PerlinNoiseGM2 : public skiagm::GM {
106 public:
PerlinNoiseGM2()107     PerlinNoiseGM2() {
108         fSize = SkISize::Make(80, 80);
109     }
110 
111 protected:
onShortName()112     virtual SkString onShortName() {
113         return SkString("perlinnoise_localmatrix");
114     }
115 
onISize()116     virtual SkISize onISize() {
117         return SkISize::Make(640, 480);
118     }
119 
install(SkPaint * paint,Type type,float baseFrequencyX,float baseFrequencyY,int numOctaves,float seed,bool stitchTiles)120     void install(SkPaint* paint, Type type,
121               float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed,
122               bool stitchTiles) {
123         sk_sp<SkShader> shader = (type == Type::kFractalNoise) ?
124             SkPerlinNoiseShader::MakeFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves,
125                                                   seed, stitchTiles ? &fSize : nullptr) :
126             SkPerlinNoiseShader::MakeTurbulence(baseFrequencyX, baseFrequencyY, numOctaves,
127                                                 seed, stitchTiles ? &fSize : nullptr);
128         paint->setShader(std::move(shader));
129     }
130 
onDraw(SkCanvas * canvas)131     virtual void onDraw(SkCanvas* canvas) {
132         canvas->translate(10, 10);
133 
134         SkPaint paint;
135         this->install(&paint, Type::kFractalNoise, 0.1f, 0.1f, 2, 0, false);
136 
137         const SkScalar w = SkIntToScalar(fSize.width());
138         const SkScalar h = SkIntToScalar(fSize.height());
139 
140         SkRect r = SkRect::MakeWH(w, h);
141         canvas->drawRect(r, paint);
142 
143         canvas->save();
144         canvas->translate(w * 5/4, 0);
145         canvas->drawRect(r, paint);
146         canvas->restore();
147 
148         canvas->save();
149         canvas->translate(0, h + 10);
150         canvas->scale(2, 2);
151         canvas->drawRect(r, paint);
152         canvas->restore();
153 
154         canvas->save();
155         canvas->translate(w + 100, h + 10);
156         canvas->scale(2, 2);
157         canvas->drawRect(r, paint);
158         canvas->restore();
159 
160         // The next row should draw the same as the previous, even though we are using a local
161         // matrix instead of the canvas.
162 
163         canvas->translate(0, h * 2 + 10);
164 
165         SkMatrix lm;
166         lm.setScale(2, 2);
167         paint.setShader(paint.getShader()->makeWithLocalMatrix(lm));
168         r.fRight += r.width();
169         r.fBottom += r.height();
170 
171         canvas->save();
172         canvas->translate(0, h + 10);
173         canvas->drawRect(r, paint);
174         canvas->restore();
175 
176         canvas->save();
177         canvas->translate(w + 100, h + 10);
178         canvas->drawRect(r, paint);
179         canvas->restore();
180     }
181 
182 private:
183     typedef GM INHERITED;
184     SkISize fSize;
185 };
186 
187 //////////////////////////////////////////////////////////////////////////////
188 
189 DEF_GM( return new PerlinNoiseGM; )
190 DEF_GM( return new PerlinNoiseGM2; )
191