• Home
  • 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 "include/core/SkPoint3.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/private/SkTArray.h"
15 
16 class SkReadBuffer;
17 class SkWriteBuffer;
18 
19 /** \class SkLights
20     SkLights encapsulates a set of directional, point and ambient lights for use with the
21     SkLightingShader.
22 */
23 class SK_API SkLights  : public SkRefCnt {
24 public:
25     class Light {
26     public:
27         enum LightType {
28             kDirectional_LightType,
29             kPoint_LightType
30         };
31 
Light(const Light & other)32         Light(const Light& other)
33                 : fType(other.fType)
34                 , fColor(other.fColor)
35                 , fDirOrPos(other.fDirOrPos)
36                 , fIntensity(other.fIntensity) {}
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 
MakeDirectional(const SkColor3f & color,const SkVector3 & dir)44         static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir) {
45             Light light(kDirectional_LightType, color, dir, 0.0f);
46             if (!light.fDirOrPos.normalize()) {
47                 light.fDirOrPos.set(0.0f, 0.0f, 1.0f);
48             }
49             return light;
50         }
51 
MakePoint(const SkColor3f & color,const SkPoint3 & pos,SkScalar intensity)52         static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity) {
53             return Light(kPoint_LightType, color, pos, intensity);
54         }
55 
type()56         LightType type() const { return fType; }
color()57         const SkColor3f& color() const { return fColor; }
dir()58         const SkVector3& dir() const {
59             SkASSERT(kDirectional_LightType == fType);
60             return fDirOrPos;
61         }
pos()62         const SkPoint3& pos() const {
63             SkASSERT(kPoint_LightType == fType);
64             return fDirOrPos;
65         }
intensity()66         SkScalar intensity() const {
67             SkASSERT(kPoint_LightType == fType);
68             return fIntensity;
69         }
70 
71         Light& operator=(const Light& other) {
72             if (this == &other) {
73                 return *this;
74             }
75 
76             fType = other.fType;
77             fColor = other.fColor;
78             fDirOrPos = other.fDirOrPos;
79             fIntensity = other.fIntensity;
80             return *this;
81         }
82 
83         bool operator==(const Light& other) {
84             return (fType      == other.fType) &&
85                    (fColor     == other.fColor) &&
86                    (fDirOrPos  == other.fDirOrPos) &&
87                    (fIntensity == other.fIntensity);
88         }
89 
90         bool operator!=(const Light& other) { return !(this->operator==(other)); }
91 
92     private:
93         friend class SkLights;
94 
Light(LightType type,const SkColor3f & color,const SkVector3 & dirOrPos,SkScalar intensity)95         Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos,
96               SkScalar intensity)
97                 : fType(type)
98                 , fColor(color)
99                 , fDirOrPos(dirOrPos)
100                 , fIntensity(intensity) {}
101 
102         LightType   fType;
103         SkColor3f   fColor;           // linear (unpremul) color. Range is 0..1 in each channel.
104 
105         SkVector3   fDirOrPos;        // For directional lights, holds the direction towards the
106                                       // light (+Z is out of the screen).
107                                       // If degenerate, it will be replaced with (0, 0, 1).
108                                       // For point lights, holds location of point light
109 
110         SkScalar    fIntensity;       // For point lights, dictates the light intensity.
111                                       // Simply a multiplier to the final light output value.
112     };
113 
114     class Builder {
115     public:
Builder()116         Builder() : fLights(new SkLights) {}
117 
add(const Light & light)118         void add(const Light& light) {
119             if (fLights) {
120                 fLights->fLights.push_back(light);
121             }
122         }
123 
add(Light && light)124         void add(Light&& light) {
125             if (fLights) {
126                 fLights->fLights.push_back(std::move(light));
127             }
128         }
129 
setAmbientLightColor(const SkColor3f & color)130         void setAmbientLightColor(const SkColor3f& color) {
131             if (fLights) {
132                 fLights->fAmbientLightColor = color;
133             }
134         }
135 
finish()136         sk_sp<SkLights> finish() {
137             return std::move(fLights);
138         }
139 
140     private:
141         sk_sp<SkLights> fLights;
142     };
143 
144     /** Returns number of lights not including the ambient light.
145 
146         @return number of lights not including the ambient light
147     */
numLights()148     int numLights() const { return fLights.count(); }
149 
150     /** Returns the index-th light.
151 
152         @param index  the index of the desired light
153         @return       the index-th light
154     */
light(int index)155     const Light& light(int index) const { return fLights[index]; }
156 
157     /** Returns the ambient light.
158 
159         @return the ambient light
160     */
ambientLightColor()161     const SkColor3f& ambientLightColor() const {
162         return fAmbientLightColor;
163     }
164 
165     /**
166      *  Recreate an SkLights object that was serialized into a buffer.
167      *
168      *  @param  SkReadBuffer Serialized blob data.
169      *  @return A new SkLights representing the serialized data, or NULL if the buffer is
170      *          invalid.
171      */
172     static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf);
173 
174     /**
175      *  Serialize to a buffer.
176      *
177      *  @param  buffer the write buffer to write out to
178      */
179     void flatten(SkWriteBuffer& buf) const;
180 
181 private:
182     friend class SkLightingShaderImpl;
183 
SkLights()184     SkLights() : fAmbientLightColor(SkColor3f::Make(0.0f, 0.0f, 0.0f)) {}
185 
186     SkTArray<Light> fLights;
187     SkColor3f       fAmbientLightColor;
188 
189     typedef SkRefCnt INHERITED;
190 };
191 
192 #endif
193