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