| |
| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SkLights_DEFINED |
| #define SkLights_DEFINED |
| |
| #include "SkPoint3.h" |
| #include "SkRefCnt.h" |
| #include "../private/SkTArray.h" |
| |
| class SkReadBuffer; |
| class SkWriteBuffer; |
| |
| /** \class SkLights |
| SkLights encapsulates a set of directional, point and ambient lights for use with the |
| SkLightingShader. |
| */ |
| class SK_API SkLights : public SkRefCnt { |
| public: |
| class Light { |
| public: |
| enum LightType { |
| kDirectional_LightType, |
| kPoint_LightType |
| }; |
| |
| Light(const Light& other) |
| : fType(other.fType) |
| , fColor(other.fColor) |
| , fDirOrPos(other.fDirOrPos) |
| , fIntensity(other.fIntensity) {} |
| |
| Light(Light&& other) |
| : fType(other.fType) |
| , fColor(other.fColor) |
| , fDirOrPos(other.fDirOrPos) |
| , fIntensity(other.fIntensity) {} |
| |
| static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir) { |
| Light light(kDirectional_LightType, color, dir, 0.0f); |
| if (!light.fDirOrPos.normalize()) { |
| light.fDirOrPos.set(0.0f, 0.0f, 1.0f); |
| } |
| return light; |
| } |
| |
| static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity) { |
| return Light(kPoint_LightType, color, pos, intensity); |
| } |
| |
| LightType type() const { return fType; } |
| const SkColor3f& color() const { return fColor; } |
| const SkVector3& dir() const { |
| SkASSERT(kDirectional_LightType == fType); |
| return fDirOrPos; |
| } |
| const SkPoint3& pos() const { |
| SkASSERT(kPoint_LightType == fType); |
| return fDirOrPos; |
| } |
| SkScalar intensity() const { |
| SkASSERT(kPoint_LightType == fType); |
| return fIntensity; |
| } |
| |
| Light& operator=(const Light& other) { |
| if (this == &other) { |
| return *this; |
| } |
| |
| fType = other.fType; |
| fColor = other.fColor; |
| fDirOrPos = other.fDirOrPos; |
| fIntensity = other.fIntensity; |
| return *this; |
| } |
| |
| bool operator==(const Light& other) { |
| return (fType == other.fType) && |
| (fColor == other.fColor) && |
| (fDirOrPos == other.fDirOrPos) && |
| (fIntensity == other.fIntensity); |
| } |
| |
| bool operator!=(const Light& other) { return !(this->operator==(other)); } |
| |
| private: |
| friend class SkLights; |
| |
| Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos, |
| SkScalar intensity) |
| : fType(type) |
| , fColor(color) |
| , fDirOrPos(dirOrPos) |
| , fIntensity(intensity) {} |
| |
| LightType fType; |
| SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel. |
| |
| SkVector3 fDirOrPos; // For directional lights, holds the direction towards the |
| // light (+Z is out of the screen). |
| // If degenerate, it will be replaced with (0, 0, 1). |
| // For point lights, holds location of point light |
| |
| SkScalar fIntensity; // For point lights, dictates the light intensity. |
| // Simply a multiplier to the final light output value. |
| }; |
| |
| class Builder { |
| public: |
| Builder() : fLights(new SkLights) {} |
| |
| void add(const Light& light) { |
| if (fLights) { |
| fLights->fLights.push_back(light); |
| } |
| } |
| |
| void add(Light&& light) { |
| if (fLights) { |
| fLights->fLights.push_back(std::move(light)); |
| } |
| } |
| |
| void setAmbientLightColor(const SkColor3f& color) { |
| if (fLights) { |
| fLights->fAmbientLightColor = color; |
| } |
| } |
| |
| sk_sp<SkLights> finish() { |
| return std::move(fLights); |
| } |
| |
| private: |
| sk_sp<SkLights> fLights; |
| }; |
| |
| /** Returns number of lights not including the ambient light. |
| |
| @return number of lights not including the ambient light |
| */ |
| int numLights() const { return fLights.count(); } |
| |
| /** Returns the index-th light. |
| |
| @param index the index of the desired light |
| @return the index-th light |
| */ |
| const Light& light(int index) const { return fLights[index]; } |
| |
| /** Returns the ambient light. |
| |
| @return the ambient light |
| */ |
| const SkColor3f& ambientLightColor() const { |
| return fAmbientLightColor; |
| } |
| |
| /** |
| * Recreate an SkLights object that was serialized into a buffer. |
| * |
| * @param SkReadBuffer Serialized blob data. |
| * @return A new SkLights representing the serialized data, or NULL if the buffer is |
| * invalid. |
| */ |
| static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf); |
| |
| /** |
| * Serialize to a buffer. |
| * |
| * @param buffer the write buffer to write out to |
| */ |
| void flatten(SkWriteBuffer& buf) const; |
| |
| private: |
| friend class SkLightingShaderImpl; |
| |
| SkLights() : fAmbientLightColor(SkColor3f::Make(0.0f, 0.0f, 0.0f)) {} |
| |
| SkTArray<Light> fLights; |
| SkColor3f fAmbientLightColor; |
| |
| typedef SkRefCnt INHERITED; |
| }; |
| |
| #endif |