Added PointLights to SkLights::Light
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2237493002
Review-Url: https://codereview.chromium.org/2237493002
diff --git a/gm/lightingshader.cpp b/gm/lightingshader.cpp
index 54318ee..4a79ebe 100644
--- a/gm/lightingshader.cpp
+++ b/gm/lightingshader.cpp
@@ -48,11 +48,11 @@
SkLights::Builder builder;
- builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f),
- SkVector3::Make(SK_ScalarRoot2Over2,
- 0.0f,
- SK_ScalarRoot2Over2)));
- builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
+ SkVector3::Make(SK_ScalarRoot2Over2,
+ 0.0f,
+ SK_ScalarRoot2Over2)));
+ builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
fLights = builder.finish();
}
diff --git a/gm/lightingshader2.cpp b/gm/lightingshader2.cpp
index 5e0d19b..70c9e29 100644
--- a/gm/lightingshader2.cpp
+++ b/gm/lightingshader2.cpp
@@ -43,9 +43,9 @@
SkLights::Builder builder;
const SkVector3 kLightFromUpperRight = SkVector3::Make(0.788f, 0.394f, 0.473f);
- builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f),
- kLightFromUpperRight));
- builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
+ kLightFromUpperRight));
+ builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
fLights = builder.finish();
fRect = SkRect::MakeIWH(kTexSize, kTexSize);
diff --git a/gm/lightingshaderbevel.cpp b/gm/lightingshaderbevel.cpp
index dfc46e4..9107cc6 100644
--- a/gm/lightingshaderbevel.cpp
+++ b/gm/lightingshaderbevel.cpp
@@ -36,9 +36,9 @@
SkLights::Builder builder;
const SkVector3 kLightFromUpperRight = SkVector3::Make(0.788f, 0.394f, 0.473f);
- builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f),
- kLightFromUpperRight));
- builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
+ kLightFromUpperRight));
+ builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
fLights = builder.finish();
// fRect is assumed to be square throughout this file
diff --git a/gm/shadowmaps.cpp b/gm/shadowmaps.cpp
index b343d9b..f953550 100644
--- a/gm/shadowmaps.cpp
+++ b/gm/shadowmaps.cpp
@@ -70,11 +70,11 @@
// - soft white ambient light
SkLights::Builder builder;
- builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.3f, 0.4f),
- SkVector3::Make(0.2f, 0.1f, 1.0f)));
- builder.add(SkLights::Light(SkColor3f::Make(0.4f, 0.3f, 0.2f),
- SkVector3::Make(0.1f, 0.2f, 1.0f)));
- builder.add(SkLights::Light(SkColor3f::Make(0.4f, 0.4f, 0.4f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.2f, 0.3f, 0.4f),
+ SkVector3::Make(0.2f, 0.1f, 1.0f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.4f, 0.3f, 0.2f),
+ SkVector3::Make(0.1f, 0.2f, 1.0f)));
+ builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.4f, 0.4f, 0.4f)));
fLights = builder.finish();
}
diff --git a/gyp/core.gypi b/gyp/core.gypi
index 13b7ef6..8d1dc8d 100644
--- a/gyp/core.gypi
+++ b/gyp/core.gypi
@@ -152,6 +152,7 @@
'<(skia_src_path)/core/SkImageGeneratorPriv.h',
'<(skia_src_path)/core/SkLightingShader.h',
'<(skia_src_path)/core/SkLightingShader.cpp',
+ '<(skia_src_path)/core/SkLights.cpp',
'<(skia_src_path)/core/SkLinearBitmapPipeline.cpp',
'<(skia_src_path)/core/SkLinearBitmapPipeline.h',
'<(skia_src_path)/core/SkLinearBitmapPipeline_core.h',
diff --git a/include/core/SkLights.h b/include/core/SkLights.h
index 52e60c7..d9ec65b 100644
--- a/include/core/SkLights.h
+++ b/include/core/SkLights.h
@@ -9,10 +9,13 @@
#ifndef SkLights_DEFINED
#define SkLights_DEFINED
+#include "../private/SkTArray.h"
#include "SkPoint3.h"
#include "SkRefCnt.h"
-#include "../private/SkTArray.h"
-#include "SkImage.h"
+
+class SkReadBuffer;
+class SkWriteBuffer;
+class SkImage;
class SK_API SkLights : public SkRefCnt {
public:
@@ -20,7 +23,8 @@
public:
enum LightType {
kAmbient_LightType, // only 'fColor' is used
- kDirectional_LightType
+ kDirectional_LightType,
+ kPoint_LightType
};
Light(const Light& other)
@@ -37,26 +41,31 @@
, fShadowMap(std::move(other.fShadowMap)) {
}
- Light(const SkColor3f& color)
- : fType(kAmbient_LightType)
- , fColor(color) {
- fDirection.set(0.0f, 0.0f, 1.0f);
+ static Light MakeAmbient(const SkColor3f& color) {
+ return Light(kAmbient_LightType, color, SkVector3::Make(0.0f, 0.0f, 1.0f));
}
- Light(const SkColor3f& color, const SkVector3& dir)
- : fType(kDirectional_LightType)
- , fColor(color)
- , fDirection(dir) {
- if (!fDirection.normalize()) {
- fDirection.set(0.0f, 0.0f, 1.0f);
+ static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir) {
+ Light light(kDirectional_LightType, color, dir);
+ if (!light.fDirection.normalize()) {
+ light.fDirection.set(0.0f, 0.0f, 1.0f);
}
+ return light;
+ }
+
+ static Light MakePoint(const SkColor3f& color, const SkPoint3& pos) {
+ return Light(kPoint_LightType, color, pos);
}
LightType type() const { return fType; }
const SkColor3f& color() const { return fColor; }
- const SkVector3& dir() const {
- SkASSERT(kAmbient_LightType != fType);
- return fDirection;
+ const SkVector3& dir() const {
+ SkASSERT(kDirectional_LightType == fType);
+ return fDirection;
+ }
+ const SkPoint3& pos() const {
+ SkASSERT(kPoint_LightType == fType);
+ return fDirection;
}
void setShadowMap(sk_sp<SkImage> shadowMap) {
@@ -78,19 +87,26 @@
fShadowMap = b.fShadowMap;
return *this;
}
-
private:
LightType fType;
SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel.
- SkVector3 fDirection; // direction towards the light (+Z is out of the screen).
+ SkVector3 fDirection; // 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
sk_sp<SkImage> fShadowMap;
+
+ Light(LightType type, const SkColor3f& color, const SkVector3& dir) {
+ fType = type;
+ fColor = color;
+ fDirection = dir;
+ }
};
class Builder {
public:
Builder() : fLights(new SkLights) { }
-
+
void add(const Light& light) {
if (fLights) {
fLights->fLights.push_back(light);
@@ -123,11 +139,13 @@
return fLights[index];
}
+ static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf);
+
+ void flatten(SkWriteBuffer& buf) const;
+
private:
SkLights() {}
-
SkTArray<Light> fLights;
-
typedef SkRefCnt INHERITED;
};
diff --git a/samplecode/SampleLighting.cpp b/samplecode/SampleLighting.cpp
index 1c86c99..bab2b5d 100755
--- a/samplecode/SampleLighting.cpp
+++ b/samplecode/SampleLighting.cpp
@@ -21,8 +21,8 @@
SkLights::Builder builder;
- builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, blue), dir));
- builder.add(SkLights::Light(SkColor3f::Make(0.1f, 0.1f, 0.1f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, blue), dir));
+ builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.1f, 0.1f, 0.1f)));
return builder.finish();
}
diff --git a/samplecode/SampleLitAtlas.cpp b/samplecode/SampleLitAtlas.cpp
index 5f62e2a..cb49bf3 100644
--- a/samplecode/SampleLitAtlas.cpp
+++ b/samplecode/SampleLitAtlas.cpp
@@ -182,8 +182,9 @@
void updateLights() {
SkLights::Builder builder;
- builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f), fLightDir));
- builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
+ builder.add(SkLights::Light::MakeDirectional(
+ SkColor3f::Make(1.0f, 1.0f, 1.0f), fLightDir));
+ builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
fLights = builder.finish();
}
diff --git a/samplecode/SampleShadowing.cpp b/samplecode/SampleShadowing.cpp
index 7b434bc..d0b37fb 100644
--- a/samplecode/SampleShadowing.cpp
+++ b/samplecode/SampleShadowing.cpp
@@ -19,11 +19,11 @@
this->setBGColor(0xFFCCCCCC);
SkLights::Builder builder;
- builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.3f, 0.4f),
- SkVector3::Make(0.2f, 0.05f, 1.0f)));
- builder.add(SkLights::Light(SkColor3f::Make(0.4f, 0.3f, 0.2f),
- SkVector3::Make(0.05f, 0.2f, 1.0f)));
- builder.add(SkLights::Light(SkColor3f::Make(0.4f, 0.4f, 0.4f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.2f, 0.3f, 0.4f),
+ SkVector3::Make(0.2f, 0.05f, 1.0f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(0.4f, 0.3f, 0.2f),
+ SkVector3::Make(0.05f, 0.2f, 1.0f)));
+ builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.4f, 0.4f, 0.4f)));
fLights = builder.finish();
fTestRects[0].fColor = 0xFFEE8888;
@@ -139,15 +139,18 @@
float recipY = 1.0f / kHeight;
SkLights::Builder builder;
- builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.3f, 0.4f),
- SkVector3::Make(0.2f + (200.0f - x) * recipX,
- 0.05f + (200.0f - y) * recipY,
- 1.0f)));
- builder.add(SkLights::Light(SkColor3f::Make(0.4f, 0.3f, 0.2f),
- SkVector3::Make(0.05f + (200.0f - x) * recipX,
- 0.2f + (200.0f - y) * recipY,
- 1.0f)));
- builder.add(SkLights::Light(SkColor3f::Make(0.4f, 0.4f, 0.4f)));
+ builder.add(SkLights::Light::MakeDirectional(
+ SkColor3f::Make(0.2f, 0.3f, 0.4f),
+ SkVector3::Make(0.2f + (200.0f - x) * recipX,
+ 0.05f + (200.0f - y) * recipY,
+ 1.0f)));
+ builder.add(SkLights::Light::MakeDirectional(
+ SkColor3f::Make(0.4f, 0.3f, 0.2f),
+ SkVector3::Make(0.05f + (200.0f - x) * recipX,
+ 0.2f + (200.0f - y) * recipY,
+ 1.0f)));
+ builder.add(SkLights::Light::MakeAmbient(
+ SkColor3f::Make(0.4f, 0.4f, 0.4f)));
fLights = builder.finish();
fLightsChanged = true;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 4160df7..d199e5d 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -3198,8 +3198,8 @@
// povDepthMap
{
SkLights::Builder builder;
- builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f),
- SkVector3::Make(0.0f, 0.0f, 1.0f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
+ SkVector3::Make(0.0f, 0.0f, 1.0f)));
sk_sp<SkLights> povLight = builder.finish();
SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(),
diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp
index e8280b1..6f3c233 100644
--- a/src/core/SkLightingShader.cpp
+++ b/src/core/SkLightingShader.cpp
@@ -416,30 +416,7 @@
bool hasLocalMatrix = buf.readBool();
SkAssertResult(!hasLocalMatrix);
- int numLights = buf.readInt();
-
- SkLights::Builder builder;
-
- for (int l = 0; l < numLights; ++l) {
- bool isAmbient = buf.readBool();
-
- SkColor3f color;
- if (!buf.readScalarArray(&color.fX, 3)) {
- return nullptr;
- }
-
- if (isAmbient) {
- builder.add(SkLights::Light(color));
- } else {
- SkVector3 dir;
- if (!buf.readScalarArray(&dir.fX, 3)) {
- return nullptr;
- }
- builder.add(SkLights::Light(color, dir));
- }
- }
-
- sk_sp<SkLights> lights(builder.finish());
+ sk_sp<SkLights> lights = SkLights::MakeFromBuffer(buf);
sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>());
@@ -456,18 +433,7 @@
void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
this->INHERITED::flatten(buf);
- buf.writeInt(fLights->numLights());
- for (int l = 0; l < fLights->numLights(); ++l) {
- const SkLights::Light& light = fLights->light(l);
-
- bool isAmbient = SkLights::Light::kAmbient_LightType == light.type();
-
- buf.writeBool(isAmbient);
- buf.writeScalarArray(&light.color().fX, 3);
- if (!isAmbient) {
- buf.writeScalarArray(&light.dir().fX, 3);
- }
- }
+ fLights->flatten(buf);
buf.writeFlattenable(fNormalSource.get());
buf.writeBool(fDiffuseShader);
diff --git a/src/core/SkLights.cpp b/src/core/SkLights.cpp
new file mode 100644
index 0000000..a172de4
--- /dev/null
+++ b/src/core/SkLights.cpp
@@ -0,0 +1,77 @@
+
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkLights.h"
+#include "SkReadBuffer.h"
+
+sk_sp<SkLights> SkLights::MakeFromBuffer(SkReadBuffer& buf) {
+ int numLights = buf.readInt();
+
+ Builder builder;
+ for (int l = 0; l < numLights; ++l) {
+ bool isAmbient = buf.readBool();
+ bool isPoint = buf.readBool();
+
+ SkColor3f color;
+ if (!buf.readScalarArray(&color.fX, 3)) {
+ return nullptr;
+ }
+
+ if (isAmbient) {
+ builder.add(Light::MakeAmbient(color));
+ } else {
+ SkVector3 dirOrPos;
+ if (!buf.readScalarArray(&dirOrPos.fX, 3)) {
+ return nullptr;
+ }
+
+ sk_sp<SkImage> depthMap;
+ bool hasShadowMap = buf.readBool();
+ if (hasShadowMap) {
+ if (!(depthMap = buf.readImage())) {
+ return nullptr;
+ }
+ }
+
+ if (isPoint) {
+ Light light = Light::MakePoint(color, dirOrPos);
+ light.setShadowMap(depthMap);
+ builder.add(light);
+ } else {
+ Light light = Light::MakeDirectional(color, dirOrPos);
+ light.setShadowMap(depthMap);
+ builder.add(light);
+ }
+ }
+ }
+
+ return builder.finish();
+}
+
+void SkLights::flatten(SkWriteBuffer& buf) const {
+
+ buf.writeInt(this->numLights());
+ for (int l = 0; l < this->numLights(); ++l) {
+ const Light& light = this->light(l);
+
+ bool isAmbient = Light::kAmbient_LightType == light.type();
+ bool isPoint = Light::kPoint_LightType == light.type();
+
+ buf.writeBool(isAmbient);
+ buf.writeBool(isPoint);
+ buf.writeScalarArray(&light.color().fX, 3);
+ if (!isAmbient) {
+ buf.writeScalarArray(&light.dir().fX, 3);
+ bool hasShadowMap = light.getShadowMap() != nullptr;
+ buf.writeBool(hasShadowMap);
+ if (hasShadowMap) {
+ buf.writeImage(light.getShadowMap());
+ }
+ }
+ }
+}
diff --git a/src/core/SkShadowShader.cpp b/src/core/SkShadowShader.cpp
index 5fc992a..8042583 100644
--- a/src/core/SkShadowShader.cpp
+++ b/src/core/SkShadowShader.cpp
@@ -592,39 +592,7 @@
bool hasLocalMatrix = buf.readBool();
SkAssertResult(!hasLocalMatrix);
- int numLights = buf.readInt();
-
- SkLights::Builder builder;
-
- for (int l = 0; l < numLights; ++l) {
- bool isAmbient = buf.readBool();
-
- SkColor3f color;
- if (!buf.readScalarArray(&color.fX, 3)) {
- return nullptr;
- }
-
- if (isAmbient) {
- builder.add(SkLights::Light(color));
- } else {
- SkVector3 dir;
- if (!buf.readScalarArray(&dir.fX, 3)) {
- return nullptr;
- }
-
- sk_sp<SkImage> depthMap;
- if (!(depthMap = sk_ref_sp<SkImage>(buf.readImage()))) {
- return nullptr;
- }
-
- SkLights::Light light = SkLights::Light(color, dir);
- light.setShadowMap(depthMap);
-
- builder.add(light);
- }
- }
-
- sk_sp<SkLights> lights(builder.finish());
+ sk_sp<SkLights> lights = SkLights::MakeFromBuffer(buf);
int diffuseWidth = buf.readInt();
int diffuseHeight = buf.readInt();
@@ -641,21 +609,7 @@
void SkShadowShaderImpl::flatten(SkWriteBuffer& buf) const {
this->INHERITED::flatten(buf);
- buf.writeInt(fLights->numLights());
-
- for (int l = 0; l < fLights->numLights(); ++l) {
- const SkLights::Light& light = fLights->light(l);
-
- bool isAmbient = SkLights::Light::kAmbient_LightType == light.type();
-
- buf.writeBool(isAmbient);
- buf.writeScalarArray(&light.color().fX, 3);
- if (!isAmbient) {
- buf.writeScalarArray(&light.dir().fX, 3);
- }
-
- buf.writeImage(light.getShadowMap());
- }
+ fLights->flatten(buf);
buf.writeInt(fDiffuseWidth);
buf.writeInt(fDiffuseHeight);
diff --git a/tests/SerializationTest.cpp b/tests/SerializationTest.cpp
index 86591b5..11a705f 100644
--- a/tests/SerializationTest.cpp
+++ b/tests/SerializationTest.cpp
@@ -556,9 +556,9 @@
SkLights::Builder builder;
- builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f),
- SkVector3::Make(1.0f, 0.0f, 0.0f)));
- builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
+ builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f),
+ SkVector3::Make(1.0f, 0.0f, 0.0f)));
+ builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.2f, 0.2f, 0.2f)));
sk_sp<SkLights> fLights = builder.finish();