OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkPerlinNoiseShader_DEFINED | 8 #ifndef SkPerlinNoiseShader_DEFINED |
9 #define SkPerlinNoiseShader_DEFINED | 9 #define SkPerlinNoiseShader_DEFINED |
10 | 10 |
11 #include "SkBitmap.h" | |
12 #include "SkPoint.h" | |
11 #include "SkShader.h" | 13 #include "SkShader.h" |
12 | 14 |
13 /** \class SkPerlinNoiseShader | 15 /** \class SkPerlinNoiseShader |
14 | 16 |
15 SkPerlinNoiseShader creates an image using the Perlin turbulence function. | 17 SkPerlinNoiseShader creates an image using the Perlin turbulence function. |
16 | 18 |
17 It can produce tileable noise if asked to stitch tiles and provided a tile s ize. | 19 It can produce tileable noise if asked to stitch tiles and provided a tile s ize. |
18 In order to fill a large area with repeating noise, set the stitchTiles flag to | 20 In order to fill a large area with repeating noise, set the stitchTiles flag to |
19 true, and render exactly a single tile of noise. Without this flag, the resu lt | 21 true, and render exactly a single tile of noise. Without this flag, the resu lt |
20 will contain visible seams between tiles. | 22 will contain visible seams between tiles. |
21 | 23 |
22 The algorithm used is described here : | 24 The algorithm used is described here : |
23 http://www.w3.org/TR/SVG/filters.html#feTurbulenceElement | 25 http://www.w3.org/TR/SVG/filters.html#feTurbulenceElement |
24 */ | 26 */ |
25 class SK_API SkPerlinNoiseShader : public SkShader { | 27 class SK_API SkPerlinNoiseShader : public SkShader { |
26 struct PaintingData; | |
27 public: | 28 public: |
28 struct StitchData; | |
29 | |
30 /** | 29 /** |
31 * About the noise types : the difference between the 2 is just minor tweak s to the algorithm, | 30 * About the noise types : the difference between the 2 is just minor tweak s to the algorithm, |
32 * they're not 2 entirely different noises. The output looks different, but once the noise is | 31 * they're not 2 entirely different noises. The output looks different, but once the noise is |
33 * generated in the [1, -1] range, the output is brought back in the [0, 1] range by doing : | 32 * generated in the [1, -1] range, the output is brought back in the [0, 1] range by doing : |
34 * kFractalNoise_Type : noise * 0.5 + 0.5 | 33 * kFractalNoise_Type : noise * 0.5 + 0.5 |
35 * kTurbulence_Type : abs(noise) | 34 * kTurbulence_Type : abs(noise) |
36 * Very little differences between the 2 types, although you can tell the d ifference visually. | 35 * Very little differences between the 2 types, although you can tell the d ifference visually. |
37 */ | 36 */ |
38 enum Type { | 37 enum Type { |
39 kFractalNoise_Type, | 38 kFractalNoise_Type, |
(...skipping 22 matching lines...) Expand all Loading... | |
62 int numOctaves, SkScalar seed, | 61 int numOctaves, SkScalar seed, |
63 const SkISize* tileSize = NULL); | 62 const SkISize* tileSize = NULL); |
64 | 63 |
65 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, | 64 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, |
66 const SkMatrix& matrix); | 65 const SkMatrix& matrix); |
67 virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; | 66 virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; |
68 virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE; | 67 virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE; |
69 | 68 |
70 virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const S K_OVERRIDE; | 69 virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const S K_OVERRIDE; |
71 | 70 |
71 struct StitchData { | |
scroggo
2014/03/04 22:26:34
StitchData is now defined in the class declaration
| |
72 StitchData() | |
73 : fWidth(0) | |
74 , fWrapX(0) | |
75 , fHeight(0) | |
76 , fWrapY(0) | |
77 {} | |
78 | |
79 bool operator==(const StitchData& other) const { | |
80 return fWidth == other.fWidth && | |
81 fWrapX == other.fWrapX && | |
82 fHeight == other.fHeight && | |
83 fWrapY == other.fWrapY; | |
84 } | |
85 | |
86 int fWidth; // How much to subtract to wrap for stitching. | |
87 int fWrapX; // Minimum value to wrap. | |
88 int fHeight; | |
89 int fWrapY; | |
90 }; | |
91 | |
72 SK_DEVELOPER_TO_STRING() | 92 SK_DEVELOPER_TO_STRING() |
73 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader) | 93 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader) |
74 | 94 |
75 protected: | 95 protected: |
76 SkPerlinNoiseShader(SkReadBuffer&); | 96 SkPerlinNoiseShader(SkReadBuffer&); |
77 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; | 97 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; |
78 | 98 |
79 private: | 99 private: |
80 SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, SkScalar baseFrequencyX, | 100 SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, SkScalar baseFrequencyX, |
81 SkScalar baseFrequencyY, int numOctaves, SkScalar seed, | 101 SkScalar baseFrequencyY, int numOctaves, SkScalar seed, |
82 const SkISize* tileSize = NULL); | 102 const SkISize* tileSize = NULL); |
83 virtual ~SkPerlinNoiseShader(); | |
84 | 103 |
85 void setTileSize(const SkISize&); | 104 SkScalar noise2D(int channel, const StitchData& stitchData, const SkPoint& n oiseVector) const; |
86 | 105 |
87 void initPaint(PaintingData& paintingData); | 106 SkScalar calculateTurbulenceValueForPoint(int channel, StitchData& stitchDat a, |
107 const SkPoint& point) const; | |
88 | 108 |
89 SkScalar noise2D(int channel, const PaintingData& paintingData, | 109 SkPMColor shade(const SkPoint& point, StitchData& stitchData) const; |
90 const StitchData& stitchData, const SkPoint& noiseVector); | |
91 | 110 |
92 SkScalar calculateTurbulenceValueForPoint(int channel, const PaintingData& p aintingData, | 111 // TODO (scroggo): Investigate making fields const. |
93 StitchData& stitchData, const SkPo int& point); | 112 SkPerlinNoiseShader::Type fType; |
113 SkVector fBaseFrequency; | |
114 int fNumOctaves; | |
115 // fSeed changes on each call to random. | |
116 mutable int fSeed; | |
scroggo
2014/03/04 22:26:34
fSeed is now an int, like PaintingData::fSeed was.
| |
117 SkISize fTileSize; | |
118 bool fStitchTiles; | |
94 | 119 |
95 SkPMColor shade(const SkPoint& point, StitchData& stitchData); | 120 static const int kBlockSize = 256; |
scroggo
2014/03/04 22:26:34
Now defined here for members referencing it that u
| |
121 static const int kBlockMask = kBlockSize - 1; | |
96 | 122 |
97 SkPerlinNoiseShader::Type fType; | 123 uint8_t fLatticeSelector[kBlockSize]; |
98 SkScalar fBaseFrequencyX; | 124 uint16_t fNoise[4][kBlockSize][2]; |
99 SkScalar fBaseFrequencyY; | 125 SkPoint fGradient[4][kBlockSize]; |
100 int fNumOctaves; | 126 |
101 SkScalar fSeed; | 127 StitchData fStitchDataInit; |
102 SkISize fTileSize; | 128 |
103 bool fStitchTiles; | 129 // These are caches. Instead of accessing directly, getPermutationsBitmap an d getNoiseBitmap |
130 // should be called. | |
131 mutable SkBitmap fPermutationsBitmap; | |
scroggo
2014/03/04 22:26:34
I changed these from pointers on fPaintingData to
| |
132 mutable SkBitmap fNoiseBitmap; | |
133 | |
134 | |
135 // TODO (scroggo): Once setContext creates a new object, place this on that object. | |
104 SkMatrix fMatrix; | 136 SkMatrix fMatrix; |
105 | 137 |
106 PaintingData* fPaintingData; | 138 void init(); |
scroggo
2014/03/04 22:26:34
This should now be the only function that modifies
| |
139 const SkBitmap& getPermutationsBitmap() const; | |
140 const SkBitmap& getNoiseBitmap() const; | |
107 | 141 |
108 typedef SkShader INHERITED; | 142 typedef SkShader INHERITED; |
109 }; | 143 }; |
110 | 144 |
111 #endif | 145 #endif |
OLD | NEW |