193966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 293966d88efb090f77f6109f0e19cc982b83d5da9robertphillips/* 393966d88efb090f77f6109f0e19cc982b83d5da9robertphillips * Copyright 2015 Google Inc. 493966d88efb090f77f6109f0e19cc982b83d5da9robertphillips * 593966d88efb090f77f6109f0e19cc982b83d5da9robertphillips * Use of this source code is governed by a BSD-style license that can be 693966d88efb090f77f6109f0e19cc982b83d5da9robertphillips * found in the LICENSE file. 793966d88efb090f77f6109f0e19cc982b83d5da9robertphillips */ 893966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 993966d88efb090f77f6109f0e19cc982b83d5da9robertphillips#ifndef SkLights_DEFINED 1093966d88efb090f77f6109f0e19cc982b83d5da9robertphillips#define SkLights_DEFINED 1193966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 12772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack#include "../private/SkTArray.h" 136b20a559968e1ed0d3aa4ecbd6ddda9e681b4f86Hal Canary#include "SkImage.h" 1493966d88efb090f77f6109f0e19cc982b83d5da9robertphillips#include "SkPoint3.h" 1593966d88efb090f77f6109f0e19cc982b83d5da9robertphillips#include "SkRefCnt.h" 16772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack 17772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblackclass SkReadBuffer; 18772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblackclass SkWriteBuffer; 1993966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 2093966d88efb090f77f6109f0e19cc982b83d5da9robertphillipsclass SK_API SkLights : public SkRefCnt { 2193966d88efb090f77f6109f0e19cc982b83d5da9robertphillipspublic: 2293966d88efb090f77f6109f0e19cc982b83d5da9robertphillips class Light { 2393966d88efb090f77f6109f0e19cc982b83d5da9robertphillips public: 2493966d88efb090f77f6109f0e19cc982b83d5da9robertphillips enum LightType { 25772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack kDirectional_LightType, 26772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack kPoint_LightType 2793966d88efb090f77f6109f0e19cc982b83d5da9robertphillips }; 2893966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 29a746f7894ae96558abd0775aef68d895f99dd53brobertphillips Light(const Light& other) 30a746f7894ae96558abd0775aef68d895f99dd53brobertphillips : fType(other.fType) 31a746f7894ae96558abd0775aef68d895f99dd53brobertphillips , fColor(other.fColor) 3256f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack , fDirOrPos(other.fDirOrPos) 3356f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack , fIntensity(other.fIntensity) 34c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack , fShadowMap(other.fShadowMap) 35c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack , fIsRadial(other.fIsRadial) { 36a746f7894ae96558abd0775aef68d895f99dd53brobertphillips } 37a746f7894ae96558abd0775aef68d895f99dd53brobertphillips 38a746f7894ae96558abd0775aef68d895f99dd53brobertphillips Light(Light&& other) 39a746f7894ae96558abd0775aef68d895f99dd53brobertphillips : fType(other.fType) 40a746f7894ae96558abd0775aef68d895f99dd53brobertphillips , fColor(other.fColor) 4156f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack , fDirOrPos(other.fDirOrPos) 4256f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack , fIntensity(other.fIntensity) 43c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack , fShadowMap(std::move(other.fShadowMap)) 44c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack , fIsRadial(other.fIsRadial) { 45a746f7894ae96558abd0775aef68d895f99dd53brobertphillips } 46a746f7894ae96558abd0775aef68d895f99dd53brobertphillips 47c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir, 48c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack bool isRadial = false) { 49c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack Light light(kDirectional_LightType, color, dir, isRadial); 5056f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack if (!light.fDirOrPos.normalize()) { 5156f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack light.fDirOrPos.set(0.0f, 0.0f, 1.0f); 5293966d88efb090f77f6109f0e19cc982b83d5da9robertphillips } 53772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack return light; 54772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack } 55772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack 56c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity, 57c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack bool isRadial = false) { 58c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack return Light(kPoint_LightType, color, pos, intensity, isRadial); 5993966d88efb090f77f6109f0e19cc982b83d5da9robertphillips } 6093966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 6193966d88efb090f77f6109f0e19cc982b83d5da9robertphillips LightType type() const { return fType; } 6293966d88efb090f77f6109f0e19cc982b83d5da9robertphillips const SkColor3f& color() const { return fColor; } 63772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack const SkVector3& dir() const { 64772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack SkASSERT(kDirectional_LightType == fType); 6556f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack return fDirOrPos; 66772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack } 67772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack const SkPoint3& pos() const { 68772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack SkASSERT(kPoint_LightType == fType); 6956f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack return fDirOrPos; 7056f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack } 7156f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack SkScalar intensity() const { 7256f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack SkASSERT(kPoint_LightType == fType); 7356f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack return fIntensity; 7493966d88efb090f77f6109f0e19cc982b83d5da9robertphillips } 7593966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 7695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack void setShadowMap(sk_sp<SkImage> shadowMap) { 7795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack fShadowMap = std::move(shadowMap); 7895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack } 7995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 80a746f7894ae96558abd0775aef68d895f99dd53brobertphillips SkImage* getShadowMap() const { 81a746f7894ae96558abd0775aef68d895f99dd53brobertphillips return fShadowMap.get(); 8295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack } 8395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 84c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack bool isRadial() const { return fIsRadial; } 85c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack 8695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack Light& operator= (const Light& b) { 87a746f7894ae96558abd0775aef68d895f99dd53brobertphillips if (this == &b) { 8895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack return *this; 8995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack } 9095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 91a746f7894ae96558abd0775aef68d895f99dd53brobertphillips fColor = b.fColor; 92a746f7894ae96558abd0775aef68d895f99dd53brobertphillips fType = b.fType; 9356f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack fDirOrPos = b.fDirOrPos; 9456f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack fIntensity = b.fIntensity; 95a746f7894ae96558abd0775aef68d895f99dd53brobertphillips fShadowMap = b.fShadowMap; 96c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack fIsRadial = b.fIsRadial; 9795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack return *this; 9895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack } 996ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck 1006ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck bool operator== (const Light& b) { 1016ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck if (this == &b) { 1026ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck return true; 1036ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck } 1046ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck 1056ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck return (fColor == b.fColor) && 1066ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck (fType == b.fType) && 10756f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack (fDirOrPos == b.fDirOrPos) && 10856f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack (fShadowMap == b.fShadowMap) && 109c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack (fIntensity == b.fIntensity) && 110c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack (fIsRadial == b.fIsRadial); 1116ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck } 1126ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck 1136ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck bool operator!= (const Light& b) { return !(this->operator==(b)); } 1146ad75d10eb2462e614f2b7cba293144a7e91a842dvonbeck 11593966d88efb090f77f6109f0e19cc982b83d5da9robertphillips private: 11693966d88efb090f77f6109f0e19cc982b83d5da9robertphillips LightType fType; 11793966d88efb090f77f6109f0e19cc982b83d5da9robertphillips SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel. 11856f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack 11956f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack SkVector3 fDirOrPos; // For directional lights, holds the direction towards the 120772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack // light (+Z is out of the screen). 12193966d88efb090f77f6109f0e19cc982b83d5da9robertphillips // If degenerate, it will be replaced with (0, 0, 1). 122772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack // For point lights, holds location of point light 12356f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack 12456f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack SkScalar fIntensity; // For point lights, dictates the light intensity. 12556f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack // Simply a multiplier to the final light output value. 12695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack sk_sp<SkImage> fShadowMap; 127c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack bool fIsRadial; // Whether the light is radial or not. Radial lights will 128c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack // cast shadows and lights radially outwards. 129772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack 130c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos, 131c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack SkScalar intensity = 0.0f, bool isRadial = false) { 132772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack fType = type; 133772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack fColor = color; 134a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack fDirOrPos = dirOrPos; 13556f33ea2acb39ebb041340a8ab7564facb95afcevjiaoblack fIntensity = intensity; 136c1a50e1b735bd717eed1fc72a8f093a1b399cb07vjiaoblack fIsRadial = isRadial; 137772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack } 13893966d88efb090f77f6109f0e19cc982b83d5da9robertphillips }; 13993966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 14093966d88efb090f77f6109f0e19cc982b83d5da9robertphillips class Builder { 14193966d88efb090f77f6109f0e19cc982b83d5da9robertphillips public: 142a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack Builder() : fLights(new SkLights) {} 143772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack 14493966d88efb090f77f6109f0e19cc982b83d5da9robertphillips void add(const Light& light) { 14593966d88efb090f77f6109f0e19cc982b83d5da9robertphillips if (fLights) { 146a746f7894ae96558abd0775aef68d895f99dd53brobertphillips fLights->fLights.push_back(light); 147a746f7894ae96558abd0775aef68d895f99dd53brobertphillips } 148a746f7894ae96558abd0775aef68d895f99dd53brobertphillips } 149a746f7894ae96558abd0775aef68d895f99dd53brobertphillips 150a746f7894ae96558abd0775aef68d895f99dd53brobertphillips void add(Light&& light) { 151a746f7894ae96558abd0775aef68d895f99dd53brobertphillips if (fLights) { 152a746f7894ae96558abd0775aef68d895f99dd53brobertphillips fLights->fLights.push_back(std::move(light)); 15393966d88efb090f77f6109f0e19cc982b83d5da9robertphillips } 15493966d88efb090f77f6109f0e19cc982b83d5da9robertphillips } 15593966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 156a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack void setAmbientLightColor(const SkColor3f& color) { 157a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack if (fLights) { 158a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack fLights->fAmbientLightColor = color; 159a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack } 160a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack } 161a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack 162adf5afa628adb62a0ad451d07ef1442381a0ee20robertphillips sk_sp<SkLights> finish() { 163a746f7894ae96558abd0775aef68d895f99dd53brobertphillips return std::move(fLights); 16493966d88efb090f77f6109f0e19cc982b83d5da9robertphillips } 16593966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 16693966d88efb090f77f6109f0e19cc982b83d5da9robertphillips private: 16793966d88efb090f77f6109f0e19cc982b83d5da9robertphillips sk_sp<SkLights> fLights; 16893966d88efb090f77f6109f0e19cc982b83d5da9robertphillips }; 16993966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 17093966d88efb090f77f6109f0e19cc982b83d5da9robertphillips int numLights() const { 17193966d88efb090f77f6109f0e19cc982b83d5da9robertphillips return fLights.count(); 17293966d88efb090f77f6109f0e19cc982b83d5da9robertphillips } 17393966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 17493966d88efb090f77f6109f0e19cc982b83d5da9robertphillips const Light& light(int index) const { 17593966d88efb090f77f6109f0e19cc982b83d5da9robertphillips return fLights[index]; 17693966d88efb090f77f6109f0e19cc982b83d5da9robertphillips } 17793966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 17895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack Light& light(int index) { 17995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack return fLights[index]; 18095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack } 18195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 182a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack const SkColor3f& ambientLightColor() const { 183a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack return fAmbientLightColor; 184a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack } 185a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack 186772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf); 187772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack 188772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack void flatten(SkWriteBuffer& buf) const; 189772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack 19093966d88efb090f77f6109f0e19cc982b83d5da9robertphillipsprivate: 191a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack SkLights() { 192a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack fAmbientLightColor.set(0.0f, 0.0f, 0.0f); 193a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack } 194a746f7894ae96558abd0775aef68d895f99dd53brobertphillips SkTArray<Light> fLights; 195a8eabc4a2a5559a1410fdbb348f967cd1554b325vjiaoblack SkColor3f fAmbientLightColor; 196a746f7894ae96558abd0775aef68d895f99dd53brobertphillips typedef SkRefCnt INHERITED; 19793966d88efb090f77f6109f0e19cc982b83d5da9robertphillips}; 19893966d88efb090f77f6109f0e19cc982b83d5da9robertphillips 19993966d88efb090f77f6109f0e19cc982b83d5da9robertphillips#endif 200