Skia
2DGraphicsLibrary
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkLights.h
1 
2 /*
3  * Copyright 2015 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #ifndef SkLights_DEFINED
10 #define SkLights_DEFINED
11 
12 #include "../private/SkTArray.h"
13 #include "SkImage.h"
14 #include "SkPoint3.h"
15 #include "SkRefCnt.h"
16 
17 class SkReadBuffer;
18 class SkWriteBuffer;
19 
20 class SK_API SkLights : public SkRefCnt {
21 public:
22  class Light {
23  public:
24  enum LightType {
25  kDirectional_LightType,
26  kPoint_LightType
27  };
28 
29  Light(const Light& other)
30  : fType(other.fType)
31  , fColor(other.fColor)
32  , fDirOrPos(other.fDirOrPos)
33  , fIntensity(other.fIntensity)
34  , fShadowMap(other.fShadowMap)
35  , fIsRadial(other.fIsRadial) {
36  }
37 
38  Light(Light&& other)
39  : fType(other.fType)
40  , fColor(other.fColor)
41  , fDirOrPos(other.fDirOrPos)
42  , fIntensity(other.fIntensity)
43  , fShadowMap(std::move(other.fShadowMap))
44  , fIsRadial(other.fIsRadial) {
45  }
46 
47  static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir,
48  bool isRadial = false) {
49  Light light(kDirectional_LightType, color, dir, isRadial);
50  if (!light.fDirOrPos.normalize()) {
51  light.fDirOrPos.set(0.0f, 0.0f, 1.0f);
52  }
53  return light;
54  }
55 
56  static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity,
57  bool isRadial = false) {
58  return Light(kPoint_LightType, color, pos, intensity, isRadial);
59  }
60 
61  LightType type() const { return fType; }
62  const SkColor3f& color() const { return fColor; }
63  const SkVector3& dir() const {
64  SkASSERT(kDirectional_LightType == fType);
65  return fDirOrPos;
66  }
67  const SkPoint3& pos() const {
68  SkASSERT(kPoint_LightType == fType);
69  return fDirOrPos;
70  }
71  SkScalar intensity() const {
72  SkASSERT(kPoint_LightType == fType);
73  return fIntensity;
74  }
75 
76  void setShadowMap(sk_sp<SkImage> shadowMap) {
77  fShadowMap = std::move(shadowMap);
78  }
79 
80  SkImage* getShadowMap() const {
81  return fShadowMap.get();
82  }
83 
84  bool isRadial() const { return fIsRadial; }
85 
86  Light& operator= (const Light& b) {
87  if (this == &b) {
88  return *this;
89  }
90 
91  fColor = b.fColor;
92  fType = b.fType;
93  fDirOrPos = b.fDirOrPos;
94  fIntensity = b.fIntensity;
95  fShadowMap = b.fShadowMap;
96  fIsRadial = b.fIsRadial;
97  return *this;
98  }
99 
100  bool operator== (const Light& b) {
101  if (this == &b) {
102  return true;
103  }
104 
105  return (fColor == b.fColor) &&
106  (fType == b.fType) &&
107  (fDirOrPos == b.fDirOrPos) &&
108  (fShadowMap == b.fShadowMap) &&
109  (fIntensity == b.fIntensity) &&
110  (fIsRadial == b.fIsRadial);
111  }
112 
113  bool operator!= (const Light& b) { return !(this->operator==(b)); }
114 
115  private:
116  friend class SkLights;
117 
118  LightType fType;
119  SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel.
120 
121  SkVector3 fDirOrPos; // For directional lights, holds the direction towards the
122  // light (+Z is out of the screen).
123  // If degenerate, it will be replaced with (0, 0, 1).
124  // For point lights, holds location of point light
125 
126  SkScalar fIntensity; // For point lights, dictates the light intensity.
127  // Simply a multiplier to the final light output value.
128  sk_sp<SkImage> fShadowMap;
129  bool fIsRadial; // Whether the light is radial or not. Radial lights will
130  // cast shadows and lights radially outwards.
131 
132  Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos,
133  SkScalar intensity = 0.0f, bool isRadial = false) {
134  fType = type;
135  fColor = color;
136  fDirOrPos = dirOrPos;
137  fIntensity = intensity;
138  fIsRadial = isRadial;
139  }
140  };
141 
142  class Builder {
143  public:
144  Builder() : fLights(new SkLights) {}
145 
146  void add(const Light& light) {
147  if (fLights) {
148  fLights->fLights.push_back(light);
149  }
150  }
151 
152  void add(Light&& light) {
153  if (fLights) {
154  fLights->fLights.push_back(std::move(light));
155  }
156  }
157 
158  void setAmbientLightColor(const SkColor3f& color) {
159  if (fLights) {
160  fLights->fAmbientLightColor = color;
161  }
162  }
163 
164  sk_sp<SkLights> finish() {
165  return std::move(fLights);
166  }
167 
168  private:
169  sk_sp<SkLights> fLights;
170  };
171 
172  int numLights() const {
173  return fLights.count();
174  }
175 
176  const Light& light(int index) const {
177  return fLights[index];
178  }
179 
180  Light& light(int index) {
181  return fLights[index];
182  }
183 
184  const SkColor3f& ambientLightColor() const {
185  return fAmbientLightColor;
186  }
187 
188  static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf);
189 
190  void flatten(SkWriteBuffer& buf) const;
191 
192 private:
193  SkLights() {
194  fAmbientLightColor.set(0.0f, 0.0f, 0.0f);
195  }
196 
197  friend class SkLightingShaderImpl;
198  sk_sp<SkLights> makeColorSpace(SkColorSpaceXformer* xformer) const;
199 
200  SkTArray<Light> fLights;
201  SkColor3f fAmbientLightColor;
202  typedef SkRefCnt INHERITED;
203 };
204 
205 #endif
Definition: SkPoint3.h:13
Definition: SkRefCnt.h:125
Definition: SkLights.h:20
Definition: SkLights.h:142
Definition: SkLights.h:22
bool normalize()
Set the point (vector) to be unit-length in the same direction as it already points.
Definition: SkWriteBuffer.h:27
SkImage is an abstraction for drawing a rectagle of pixels, though the particular type of image could...
Definition: SkImage.h:48