diff options
author | vjiaoblack <vjiaoblack@google.com> | 2016-08-12 11:38:47 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-08-12 11:38:47 -0700 |
commit | 772b5ee446d7545eec4ca7d6dc9d75461e2a9c38 (patch) | |
tree | 1470d1bb00cbf863ccee98a328799eb84dd31856 | |
parent | e1a3bc67690886dbc72271f447dec073363fe84c (diff) |
Added PointLights to SkLights::Light
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2237493002
Review-Url: https://codereview.chromium.org/2237493002
-rw-r--r-- | gm/lightingshader.cpp | 10 | ||||
-rw-r--r-- | gm/lightingshader2.cpp | 6 | ||||
-rw-r--r-- | gm/lightingshaderbevel.cpp | 6 | ||||
-rw-r--r-- | gm/shadowmaps.cpp | 10 | ||||
-rw-r--r-- | gyp/core.gypi | 1 | ||||
-rw-r--r-- | include/core/SkLights.h | 60 | ||||
-rwxr-xr-x | samplecode/SampleLighting.cpp | 4 | ||||
-rw-r--r-- | samplecode/SampleLitAtlas.cpp | 5 | ||||
-rw-r--r-- | samplecode/SampleShadowing.cpp | 31 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 4 | ||||
-rw-r--r-- | src/core/SkLightingShader.cpp | 38 | ||||
-rw-r--r-- | src/core/SkLights.cpp | 77 | ||||
-rw-r--r-- | src/core/SkShadowShader.cpp | 50 | ||||
-rw-r--r-- | tests/SerializationTest.cpp | 6 |
14 files changed, 164 insertions, 144 deletions
diff --git a/gm/lightingshader.cpp b/gm/lightingshader.cpp index 54318ee445..4a79ebea1d 100644 --- a/gm/lightingshader.cpp +++ b/gm/lightingshader.cpp @@ -48,11 +48,11 @@ public: 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 5e0d19b661..70c9e29f69 100644 --- a/gm/lightingshader2.cpp +++ b/gm/lightingshader2.cpp @@ -43,9 +43,9 @@ protected: 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 dfc46e4471..9107cc6c94 100644 --- a/gm/lightingshaderbevel.cpp +++ b/gm/lightingshaderbevel.cpp @@ -36,9 +36,9 @@ protected: 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 b343d9b142..f953550d4b 100644 --- a/gm/shadowmaps.cpp +++ b/gm/shadowmaps.cpp @@ -70,11 +70,11 @@ public: // - 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 13b7ef69fa..8d1dc8d177 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 52e60c71a0..d9ec65b9aa 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: public: enum LightType { kAmbient_LightType, // only 'fColor' is used - kDirectional_LightType + kDirectional_LightType, + kPoint_LightType }; Light(const Light& other) @@ -37,26 +41,31 @@ public: , 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 @@ public: 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 @@ public: 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 1c86c99362..bab2b5df92 100755 --- a/samplecode/SampleLighting.cpp +++ b/samplecode/SampleLighting.cpp @@ -21,8 +21,8 @@ static sk_sp<SkLights> create_lights(SkScalar angle, SkScalar blue) { 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 5f62e2abfb..cb49bf3872 100644 --- a/samplecode/SampleLitAtlas.cpp +++ b/samplecode/SampleLitAtlas.cpp @@ -182,8 +182,9 @@ private: 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 7b434bca80..d0b37fb15a 100644 --- a/samplecode/SampleShadowing.cpp +++ b/samplecode/SampleShadowing.cpp @@ -19,11 +19,11 @@ public: 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 @@ protected: 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 4160df7933..d199e5dd2d 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -3198,8 +3198,8 @@ void SkCanvas::onDrawShadowedPicture(const SkPicture* picture, // 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 e8280b1267..6f3c23399d 100644 --- a/src/core/SkLightingShader.cpp +++ b/src/core/SkLightingShader.cpp @@ -416,30 +416,7 @@ sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) { 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 @@ sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) { 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 0000000000..a172de4fab --- /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 5fc992acc1..804258321a 100644 --- a/src/core/SkShadowShader.cpp +++ b/src/core/SkShadowShader.cpp @@ -592,39 +592,7 @@ sk_sp<SkFlattenable> SkShadowShaderImpl::CreateProc(SkReadBuffer& buf) { 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 @@ sk_sp<SkFlattenable> SkShadowShaderImpl::CreateProc(SkReadBuffer& buf) { 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 86591b5d28..11a705f8ce 100644 --- a/tests/SerializationTest.cpp +++ b/tests/SerializationTest.cpp @@ -556,9 +556,9 @@ DEF_TEST(Serialization, reporter) { 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(); |