SkLights.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright 2015 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SkLights_DEFINED
  8. #define SkLights_DEFINED
  9. #include "include/core/SkPoint3.h"
  10. #include "include/core/SkRefCnt.h"
  11. #include "include/private/SkTArray.h"
  12. class SkReadBuffer;
  13. class SkWriteBuffer;
  14. /** \class SkLights
  15. SkLights encapsulates a set of directional, point and ambient lights for use with the
  16. SkLightingShader.
  17. */
  18. class SK_API SkLights : public SkRefCnt {
  19. public:
  20. class Light {
  21. public:
  22. enum LightType {
  23. kDirectional_LightType,
  24. kPoint_LightType
  25. };
  26. Light(const Light& other)
  27. : fType(other.fType)
  28. , fColor(other.fColor)
  29. , fDirOrPos(other.fDirOrPos)
  30. , fIntensity(other.fIntensity) {}
  31. Light(Light&& other)
  32. : fType(other.fType)
  33. , fColor(other.fColor)
  34. , fDirOrPos(other.fDirOrPos)
  35. , fIntensity(other.fIntensity) {}
  36. static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir) {
  37. Light light(kDirectional_LightType, color, dir, 0.0f);
  38. if (!light.fDirOrPos.normalize()) {
  39. light.fDirOrPos.set(0.0f, 0.0f, 1.0f);
  40. }
  41. return light;
  42. }
  43. static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity) {
  44. return Light(kPoint_LightType, color, pos, intensity);
  45. }
  46. LightType type() const { return fType; }
  47. const SkColor3f& color() const { return fColor; }
  48. const SkVector3& dir() const {
  49. SkASSERT(kDirectional_LightType == fType);
  50. return fDirOrPos;
  51. }
  52. const SkPoint3& pos() const {
  53. SkASSERT(kPoint_LightType == fType);
  54. return fDirOrPos;
  55. }
  56. SkScalar intensity() const {
  57. SkASSERT(kPoint_LightType == fType);
  58. return fIntensity;
  59. }
  60. Light& operator=(const Light& other) {
  61. if (this == &other) {
  62. return *this;
  63. }
  64. fType = other.fType;
  65. fColor = other.fColor;
  66. fDirOrPos = other.fDirOrPos;
  67. fIntensity = other.fIntensity;
  68. return *this;
  69. }
  70. bool operator==(const Light& other) {
  71. return (fType == other.fType) &&
  72. (fColor == other.fColor) &&
  73. (fDirOrPos == other.fDirOrPos) &&
  74. (fIntensity == other.fIntensity);
  75. }
  76. bool operator!=(const Light& other) { return !(this->operator==(other)); }
  77. private:
  78. friend class SkLights;
  79. Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos,
  80. SkScalar intensity)
  81. : fType(type)
  82. , fColor(color)
  83. , fDirOrPos(dirOrPos)
  84. , fIntensity(intensity) {}
  85. LightType fType;
  86. SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel.
  87. SkVector3 fDirOrPos; // For directional lights, holds the direction towards the
  88. // light (+Z is out of the screen).
  89. // If degenerate, it will be replaced with (0, 0, 1).
  90. // For point lights, holds location of point light
  91. SkScalar fIntensity; // For point lights, dictates the light intensity.
  92. // Simply a multiplier to the final light output value.
  93. };
  94. class Builder {
  95. public:
  96. Builder() : fLights(new SkLights) {}
  97. void add(const Light& light) {
  98. if (fLights) {
  99. fLights->fLights.push_back(light);
  100. }
  101. }
  102. void add(Light&& light) {
  103. if (fLights) {
  104. fLights->fLights.push_back(std::move(light));
  105. }
  106. }
  107. void setAmbientLightColor(const SkColor3f& color) {
  108. if (fLights) {
  109. fLights->fAmbientLightColor = color;
  110. }
  111. }
  112. sk_sp<SkLights> finish() {
  113. return std::move(fLights);
  114. }
  115. private:
  116. sk_sp<SkLights> fLights;
  117. };
  118. /** Returns number of lights not including the ambient light.
  119. @return number of lights not including the ambient light
  120. */
  121. int numLights() const { return fLights.count(); }
  122. /** Returns the index-th light.
  123. @param index the index of the desired light
  124. @return the index-th light
  125. */
  126. const Light& light(int index) const { return fLights[index]; }
  127. /** Returns the ambient light.
  128. @return the ambient light
  129. */
  130. const SkColor3f& ambientLightColor() const {
  131. return fAmbientLightColor;
  132. }
  133. /**
  134. * Recreate an SkLights object that was serialized into a buffer.
  135. *
  136. * @param SkReadBuffer Serialized blob data.
  137. * @return A new SkLights representing the serialized data, or NULL if the buffer is
  138. * invalid.
  139. */
  140. static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf);
  141. /**
  142. * Serialize to a buffer.
  143. *
  144. * @param buffer the write buffer to write out to
  145. */
  146. void flatten(SkWriteBuffer& buf) const;
  147. private:
  148. friend class SkLightingShaderImpl;
  149. SkLights() : fAmbientLightColor(SkColor3f::Make(0.0f, 0.0f, 0.0f)) {}
  150. SkTArray<Light> fLights;
  151. SkColor3f fAmbientLightColor;
  152. typedef SkRefCnt INHERITED;
  153. };
  154. #endif