| Index: samplecode/SampleAndroidShadows.cpp
|
| diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp
|
| index 9ab69a670c8f98a8d977c9eadd98fdbadaddbb07..38fcd204d985af6700b01811be53375886b1dbc0 100755
|
| --- a/samplecode/SampleAndroidShadows.cpp
|
| +++ b/samplecode/SampleAndroidShadows.cpp
|
| @@ -9,12 +9,15 @@
|
| #include "SkBlurMask.h"
|
| #include "SkBlurMaskFilter.h"
|
| #include "SkCanvas.h"
|
| +#include "SkGaussianEdgeShader.h"
|
| #include "SkPath.h"
|
| #include "SkPoint3.h"
|
| #include "SkUtils.h"
|
| #include "SkView.h"
|
| #include "sk_tool_utils.h"
|
|
|
| +////////////////////////////////////////////////////////////////////////////
|
| +
|
| class ShadowsView : public SampleView {
|
| SkPath fRectPath;
|
| SkPath fRRPath;
|
| @@ -22,12 +25,14 @@ class ShadowsView : public SampleView {
|
| SkPoint3 fLightPos;
|
|
|
| bool fShowAmbient;
|
| + bool fUseAltAmbient;
|
| bool fShowSpot;
|
| bool fShowObject;
|
|
|
| public:
|
| ShadowsView()
|
| : fShowAmbient(true)
|
| + , fUseAltAmbient(true)
|
| , fShowSpot(true)
|
| , fShowObject(true) {}
|
|
|
| @@ -52,6 +57,9 @@ protected:
|
| case 'B':
|
| fShowAmbient = !fShowAmbient;
|
| break;
|
| + case 'T':
|
| + fUseAltAmbient = !fUseAltAmbient;
|
| + break;
|
| case 'S':
|
| fShowSpot = !fShowSpot;
|
| break;
|
| @@ -120,10 +128,79 @@ protected:
|
| canvas->drawPath(path, paint);
|
|
|
| // draw occlusion rect
|
| +#if DRAW_OCCL_RECT
|
| SkPaint stroke;
|
| stroke.setStyle(SkPaint::kStroke_Style);
|
| stroke.setColor(SK_ColorBLUE);
|
| canvas->drawRect(occlRect, stroke);
|
| +#endif
|
| + }
|
| +
|
| + void drawAmbientShadowAlt(SkCanvas* canvas, const SkPath& path, SkScalar zValue,
|
| + SkScalar ambientAlpha) {
|
| +
|
| + if (ambientAlpha <= 0) {
|
| + return;
|
| + }
|
| +
|
| + const SkScalar kHeightFactor = 1.f / 128.f;
|
| + const SkScalar kGeomFactor = 64;
|
| +
|
| + SkScalar umbraAlpha = 1 / (1 + SkMaxScalar(zValue*kHeightFactor, 0));
|
| + SkScalar radius = zValue*kHeightFactor*kGeomFactor;
|
| +
|
| + // fast path
|
| + SkRect pathRect;
|
| + SkRRect pathRRect;
|
| + if ((path.isOval(&pathRect) && pathRect.width() == pathRect.height()) ||
|
| + (path.isRRect(&pathRRect) && pathRRect.allCornersCircular()) ||
|
| + path.isRect(&pathRect)) {
|
| +
|
| + // For all of these, we outset the rect by half the radius to get our stroke shape.
|
| + if (path.isOval(nullptr)) {
|
| + pathRect.outset(0.5f*radius, 0.5f*radius);
|
| + pathRRect = SkRRect::MakeOval(pathRect);
|
| + } else if (path.isRect(nullptr)) {
|
| + pathRect.outset(0.5f*radius, 0.5f*radius);
|
| + pathRRect = SkRRect::MakeRectXY(pathRect, 0.5f*radius, 0.5f*radius);
|
| + } else {
|
| + pathRRect.outset(0.5f*radius, 0.5f*radius);
|
| + }
|
| +
|
| + SkPaint paint;
|
| + paint.setAntiAlias(true);
|
| + paint.setColor(SkColorSetARGB((unsigned char)(ambientAlpha*umbraAlpha*255.999f),
|
| + 0, 0, 0));
|
| + paint.setStrokeWidth(radius);
|
| + paint.setStyle(SkPaint::kStroke_Style);
|
| +
|
| + paint.setShader(SkGaussianEdgeShader::Make());
|
| + canvas->drawRRect(pathRRect, paint);
|
| + } else {
|
| + // occlude blur
|
| + SkRect occlRect;
|
| + GetOcclRect(path, &occlRect);
|
| + sk_sp<SkMaskFilter> f = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
|
| + SkBlurMask::ConvertRadiusToSigma(radius),
|
| + occlRect,
|
| + SkBlurMaskFilter::kNone_BlurFlag);
|
| +
|
| + SkPaint paint;
|
| + paint.setAntiAlias(true);
|
| + paint.setMaskFilter(std::move(f));
|
| + paint.setColor(SkColorSetARGB((unsigned char)(ambientAlpha*umbraAlpha*255.999f),
|
| + 0, 0, 0));
|
| + canvas->drawPath(path, paint);
|
| +
|
| + // draw occlusion rect
|
| +#if DRAW_OCCL_RECT
|
| + SkPaint stroke;
|
| + stroke.setStyle(SkPaint::kStroke_Style);
|
| + stroke.setColor(SK_ColorBLUE);
|
| + canvas->drawRect(occlRect, stroke);
|
| +#endif
|
| + }
|
| +
|
| }
|
|
|
| void drawSpotShadow(SkCanvas* canvas, const SkPath& path, SkScalar zValue,
|
| @@ -178,10 +255,12 @@ protected:
|
| canvas->drawPath(path, paint);
|
|
|
| // draw occlusion rect
|
| +#if DRAW_OCCL_RECT
|
| SkPaint stroke;
|
| stroke.setStyle(SkPaint::kStroke_Style);
|
| stroke.setColor(SK_ColorRED);
|
| - canvas->drawRect(occlRect, stroke);
|
| + canvas->drawRect(occlRect, stroke)
|
| +#endif
|
| }
|
|
|
| void drawShadowedPath(SkCanvas* canvas, const SkPath& path, SkScalar zValue,
|
| @@ -191,7 +270,11 @@ protected:
|
| const SkScalar kSpotAlpha = 0.25f;
|
|
|
| if (fShowAmbient) {
|
| - this->drawAmbientShadow(canvas, path, zValue, kAmbientAlpha);
|
| + if (fUseAltAmbient) {
|
| + this->drawAmbientShadowAlt(canvas, path, zValue, kAmbientAlpha);
|
| + } else {
|
| + this->drawAmbientShadow(canvas, path, zValue, kAmbientAlpha);
|
| + }
|
| }
|
| if (fShowSpot) {
|
| this->drawSpotShadow(canvas, path, zValue, fLightPos, kLightWidth, kSpotAlpha);
|
| @@ -218,6 +301,10 @@ protected:
|
| paint.setColor(SK_ColorBLUE);
|
| canvas->translate(-250, 110);
|
| this->drawShadowedPath(canvas, fCirclePath, 5, paint);
|
| +
|
| + paint.setColor(SK_ColorGREEN);
|
| + canvas->translate(250, 0);
|
| + this->drawShadowedPath(canvas, fRRPath, 5, paint);
|
| }
|
|
|
| protected:
|
|
|