• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Light(const Light & other)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 
Light(Light && other)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 
type()61         LightType type() const { return fType; }
color()62         const SkColor3f& color() const { return fColor; }
dir()63         const SkVector3& dir() const {
64             SkASSERT(kDirectional_LightType == fType);
65             return fDirOrPos;
66         }
pos()67         const SkPoint3& pos() const {
68             SkASSERT(kPoint_LightType == fType);
69             return fDirOrPos;
70         }
intensity()71         SkScalar intensity() const {
72             SkASSERT(kPoint_LightType == fType);
73             return fIntensity;
74         }
75 
setShadowMap(sk_sp<SkImage> shadowMap)76         void setShadowMap(sk_sp<SkImage> shadowMap) {
77             fShadowMap = std::move(shadowMap);
78         }
79 
getShadowMap()80         SkImage* getShadowMap() const {
81             return fShadowMap.get();
82         }
83 
isRadial()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         LightType   fType;
117         SkColor3f   fColor;           // linear (unpremul) color. Range is 0..1 in each channel.
118 
119         SkVector3   fDirOrPos;        // For directional lights, holds the direction towards the
120                                       // light (+Z is out of the screen).
121                                       // If degenerate, it will be replaced with (0, 0, 1).
122                                       // For point lights, holds location of point light
123 
124         SkScalar    fIntensity;       // For point lights, dictates the light intensity.
125                                       // Simply a multiplier to the final light output value.
126         sk_sp<SkImage> fShadowMap;
127         bool        fIsRadial;        // Whether the light is radial or not. Radial lights will
128                                       // cast shadows and lights radially outwards.
129 
130         Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos,
131               SkScalar intensity = 0.0f, bool isRadial = false) {
132             fType = type;
133             fColor = color;
134             fDirOrPos = dirOrPos;
135             fIntensity = intensity;
136             fIsRadial = isRadial;
137         }
138     };
139 
140     class Builder {
141     public:
Builder()142         Builder() : fLights(new SkLights) {}
143 
add(const Light & light)144         void add(const Light& light) {
145             if (fLights) {
146                 fLights->fLights.push_back(light);
147             }
148         }
149 
add(Light && light)150         void add(Light&& light) {
151             if (fLights) {
152                 fLights->fLights.push_back(std::move(light));
153             }
154         }
155 
setAmbientLightColor(const SkColor3f & color)156         void setAmbientLightColor(const SkColor3f& color) {
157             if (fLights) {
158                 fLights->fAmbientLightColor = color;
159             }
160         }
161 
finish()162         sk_sp<SkLights> finish() {
163             return std::move(fLights);
164         }
165 
166     private:
167         sk_sp<SkLights> fLights;
168     };
169 
numLights()170     int numLights() const {
171         return fLights.count();
172     }
173 
light(int index)174     const Light& light(int index) const {
175         return fLights[index];
176     }
177 
light(int index)178     Light& light(int index) {
179         return fLights[index];
180     }
181 
ambientLightColor()182     const SkColor3f& ambientLightColor() const {
183         return fAmbientLightColor;
184     }
185 
186     static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf);
187 
188     void flatten(SkWriteBuffer& buf) const;
189 
190 private:
SkLights()191     SkLights() {
192         fAmbientLightColor.set(0.0f, 0.0f, 0.0f);
193     }
194     SkTArray<Light> fLights;
195     SkColor3f fAmbientLightColor;
196     typedef SkRefCnt INHERITED;
197 };
198 
199 #endif
200