diff options
author | vjiaoblack <vjiaoblack@google.com> | 2016-07-21 09:10:23 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-21 09:10:23 -0700 |
commit | 0ae097d116f4332be02a135ffc99c162473dee6a (patch) | |
tree | c70d5f33b9753ec7db643eeb4de6cabb927e7ed8 /include/core | |
parent | d2b6d6486ed9d00df779f6b337d756c9a818006f (diff) |
Creating framework for drawShadowedPicture
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2146073003
Review-Url: https://codereview.chromium.org/2146073003
Diffstat (limited to 'include/core')
-rw-r--r-- | include/core/SkCanvas.h | 53 | ||||
-rw-r--r-- | include/core/SkLights.h | 33 |
2 files changed, 85 insertions, 1 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 4d68a8e226..38b6f974cc 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -17,6 +17,7 @@ #include "SkRegion.h" #include "SkSurfaceProps.h" #include "SkXfermode.h" +#include "SkLights.h" class GrContext; class GrDrawContext; @@ -451,6 +452,7 @@ public: */ void resetMatrix(); +#ifdef SK_EXPERIMENTAL_SHADOWING /** Add the specified translation to the current draw depth of the canvas. @param z The distance to translate in Z. Negative into screen, positive out of screen. @@ -458,6 +460,16 @@ public: */ void translateZ(SkScalar z); + /** Set the current set of lights in the canvas. + @param lights The lights that we want the canvas to have. + */ + void setLights(sk_sp<SkLights> lights); + + /** Returns the current set of lights the canvas uses + */ + sk_sp<SkLights> getLights() const; +#endif + /** * Modify the current clip with the specified rectangle. * @param rect The rect to combine with the current clip @@ -1049,6 +1061,34 @@ public: this->drawPicture(picture.get(), matrix, paint); } +#ifdef SK_EXPERIMENTAL_SHADOWING + /** + * Draw the picture into this canvas. + * + * We will use the canvas's lights along with the picture information (draw depths of + * objects, etc) to first create a set of shadowmaps for the light-picture pairs, and + * then use that set of shadowmaps to render the scene with shadows. + * + * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is + * logically equivalent to + * save/concat/drawPicture/restore + * + * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's + * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas. + * This is logically equivalent to + * saveLayer(paint)/drawPicture/restore + * + */ + void drawShadowedPicture(const SkPicture*, + const SkMatrix* matrix, + const SkPaint* paint); + void drawShadowedPicture(const sk_sp<SkPicture>& picture, + const SkMatrix* matrix, + const SkPaint* paint) { + this->drawShadowedPicture(picture.get(), matrix, paint); + } +#endif + enum VertexMode { kTriangles_VertexMode, kTriangleStrip_VertexMode, @@ -1267,10 +1307,14 @@ public: void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds); protected: +#ifdef SK_EXPERIMENTAL_SHADOWING /** Returns the current (cumulative) draw depth of the canvas. */ SkScalar getZ() const; + sk_sp<SkLights> fLights; +#endif + /** After calling saveLayer(), there can be any number of devices that make up the top-most drawing area. LayerIter can be used to iterate through those devices. Note that the iterator is only valid until the next API @@ -1336,7 +1380,10 @@ protected: virtual void didRestore() {} virtual void didConcat(const SkMatrix&) {} virtual void didSetMatrix(const SkMatrix&) {} + +#ifdef SK_EXPERIMENTAL_SHADOWING virtual void didTranslateZ(SkScalar) {} +#endif virtual void onDrawAnnotation(const SkRect&, const char key[], SkData* value); virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&); @@ -1403,6 +1450,12 @@ protected: virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*); +#ifdef SK_EXPERIMENTAL_SHADOWING + virtual void onDrawShadowedPicture(const SkPicture*, + const SkMatrix*, + const SkPaint*); +#endif + // Returns the canvas to be used by DrawIter. Default implementation // returns this. Subclasses that encapsulate an indirect canvas may // need to overload this method. The impl must keep track of this, as it diff --git a/include/core/SkLights.h b/include/core/SkLights.h index c5c54276a3..0b23cc14aa 100644 --- a/include/core/SkLights.h +++ b/include/core/SkLights.h @@ -12,6 +12,7 @@ #include "SkPoint3.h" #include "SkRefCnt.h" #include "../private/SkTDArray.h" +#include "SkImage.h" class SK_API SkLights : public SkRefCnt { public: @@ -26,6 +27,7 @@ public: : fType(kAmbient_LightType) , fColor(color) { fDirection.set(0.0f, 0.0f, 1.0f); + fShadowMap.reset(nullptr); } Light(const SkColor3f& color, const SkVector3& dir) @@ -35,6 +37,7 @@ public: if (!fDirection.normalize()) { fDirection.set(0.0f, 0.0f, 1.0f); } + fShadowMap.reset(nullptr); } LightType type() const { return fType; } @@ -44,11 +47,35 @@ public: return fDirection; } + void setShadowMap(sk_sp<SkImage> shadowMap) { + fShadowMap = std::move(shadowMap); + } + + sk_sp<SkImage> getShadowMap() const { + return fShadowMap; + } + + Light& operator= (const Light& b) { + if (this == &b) + return *this; + + this->fColor = b.fColor; + this->fType = b.fType; + this->fDirection = b.fDirection; + + if (b.fShadowMap) { + this->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). // If degenerate, it will be replaced with (0, 0, 1). + sk_sp<SkImage> fShadowMap; }; class Builder { @@ -57,7 +84,7 @@ public: void add(const Light& light) { if (fLights) { - *fLights->fLights.push() = light; + (void) fLights->fLights.append(1, &light); } } @@ -77,6 +104,10 @@ public: return fLights[index]; } + Light& light(int index) { + return fLights[index]; + } + private: SkLights() {} |