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