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