aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core
diff options
context:
space:
mode:
authorGravatar vjiaoblack <vjiaoblack@google.com>2016-07-21 09:10:23 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-21 09:10:23 -0700
commit0ae097d116f4332be02a135ffc99c162473dee6a (patch)
treec70d5f33b9753ec7db643eeb4de6cabb927e7ed8 /include/core
parentd2b6d6486ed9d00df779f6b337d756c9a818006f (diff)
Creating framework for drawShadowedPicture
Diffstat (limited to 'include/core')
-rw-r--r--include/core/SkCanvas.h53
-rw-r--r--include/core/SkLights.h33
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() {}