diff options
author | Jim Van Verth <jvanverth@google.com> | 2017-05-04 14:00:59 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-04 18:37:55 +0000 |
commit | e7705780c9450bb190abddc47a78b8b89784ed79 (patch) | |
tree | cd04d681f4b5d19fe1e3b468f77adfef9c3b75c8 | |
parent | 3d8a374a96e1eb6a71406393af8173c93b4f08ac (diff) |
Add ShadowUtils sample.
Also enables mouse support in Viewer.
Change-Id: Iaed08d42a64f591f0cd9b24684b3aee43404ed94
Reviewed-on: https://skia-review.googlesource.com/15313
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r-- | gn/samples.gni | 1 | ||||
-rw-r--r-- | samplecode/SampleAndroidShadows.cpp | 4 | ||||
-rwxr-xr-x | samplecode/SampleShadowUtils.cpp | 225 | ||||
-rw-r--r-- | tools/viewer/Viewer.cpp | 28 | ||||
-rw-r--r-- | tools/viewer/Viewer.h | 1 |
5 files changed, 258 insertions, 1 deletions
diff --git a/gn/samples.gni b/gn/samples.gni index 7c9f4e2034..2397aa251e 100644 --- a/gn/samples.gni +++ b/gn/samples.gni @@ -82,6 +82,7 @@ samples_sources = [ "$_samplecode/SampleRepeatTile.cpp", "$_samplecode/SampleShaders.cpp", "$_samplecode/SampleShaderText.cpp", + "$_samplecode/SampleShadowUtils.cpp", "$_samplecode/SampleShip.cpp", "$_samplecode/SampleSlides.cpp", "$_samplecode/SampleStringArt.cpp", diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp index 99e5ff4556..c8ce14c8d5 100644 --- a/samplecode/SampleAndroidShadows.cpp +++ b/samplecode/SampleAndroidShadows.cpp @@ -131,6 +131,10 @@ protected: std::function<SkScalar(SkScalar, SkScalar)> zFunc, const SkPaint& paint, SkScalar ambientAlpha, const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) { + if (fIgnoreShadowAlpha) { + ambientAlpha = 255; + spotAlpha = 255; + } if (!fShowAmbient) { ambientAlpha = 0; } diff --git a/samplecode/SampleShadowUtils.cpp b/samplecode/SampleShadowUtils.cpp new file mode 100755 index 0000000000..858d212b85 --- /dev/null +++ b/samplecode/SampleShadowUtils.cpp @@ -0,0 +1,225 @@ + +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SampleCode.h" +#include "SkAnimTimer.h" +#include "SkBlurMask.h" +#include "SkBlurMaskFilter.h" +#include "SkColorFilter.h" +#include "SkCamera.h" +#include "SkCanvas.h" +#include "SkGaussianEdgeShader.h" +#include "SkPath.h" +#include "SkPathOps.h" +#include "SkPoint3.h" +#include "SkShadowUtils.h" +#include "SkUtils.h" +#include "SkView.h" +#include "sk_tool_utils.h" + +//////////////////////////////////////////////////////////////////////////// + +class ShadowUtilsView : public SampleView { + SkTArray<SkPath> fPaths; + SkScalar fZDelta; + + bool fShowAmbient; + bool fShowSpot; + bool fUseAlt; + bool fShowObject; + bool fIgnoreShadowAlpha; + +public: + ShadowUtilsView() + : fZDelta(0) + , fShowAmbient(true) + , fShowSpot(true) + , fUseAlt(false) + , fShowObject(false) + , fIgnoreShadowAlpha(false) {} + +protected: + void onOnceBeforeDraw() override { + fPaths.push_back().addRoundRect(SkRect::MakeWH(50, 50), 10, 10); + SkRRect oddRRect; + oddRRect.setNinePatch(SkRect::MakeWH(50, 50), 9, 13, 6, 16); + fPaths.push_back().addRRect(oddRRect); + fPaths.push_back().addRect(SkRect::MakeWH(50, 50)); + fPaths.push_back().addCircle(25, 25, 25); + fPaths.push_back().cubicTo(100, 50, 20, 100, 0, 0); + fPaths.push_back().addOval(SkRect::MakeWH(20, 60)); + } + + // overrides from SkEventSink + bool onQuery(SkEvent* evt) override { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "ShadowUtils"); + return true; + } + + SkUnichar uni; + if (SampleCode::CharQ(*evt, &uni)) { + bool handled = false; + switch (uni) { + case 'W': + fShowAmbient = !fShowAmbient; + handled = true; + break; + case 'S': + fShowSpot = !fShowSpot; + handled = true; + break; + case 'T': + fUseAlt = !fUseAlt; + handled = true; + break; + case 'O': + fShowObject = !fShowObject; + handled = true; + break; + case '>': + fZDelta += 0.5f; + handled = true; + break; + case '<': + fZDelta -= 0.5f; + handled = true; + break; + case '?': + fIgnoreShadowAlpha = !fIgnoreShadowAlpha; + handled = true; + break; + default: + break; + } + if (handled) { + this->inval(nullptr); + return true; + } + } + return this->INHERITED::onQuery(evt); + } + + void drawBG(SkCanvas* canvas) { + canvas->drawColor(0xFFDDDDDD); + } + + void drawShadowedPath(SkCanvas* canvas, const SkPath& path, + std::function<SkScalar(SkScalar, SkScalar)> zFunc, + const SkPaint& paint, SkScalar ambientAlpha, + const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha, + uint32_t flags) { + if (fIgnoreShadowAlpha) { + ambientAlpha = 255; + spotAlpha = 255; + } + if (!fShowAmbient) { + ambientAlpha = 0; + } + if (!fShowSpot) { + spotAlpha = 0; + } + if (fUseAlt) { + flags |= SkShadowFlags::kGeometricOnly_ShadowFlag; + } + //SkShadowUtils::DrawShadow(canvas, path, + // zValue, + // lightPos, lightWidth, + // ambientAlpha, spotAlpha, SK_ColorBLACK, flags); + SkShadowUtils::DrawUncachedShadow(canvas, path, zFunc, + lightPos, lightWidth, + ambientAlpha, 0, SK_ColorRED, flags); + SkShadowUtils::DrawUncachedShadow(canvas, path, zFunc, + lightPos, lightWidth, + 0, spotAlpha, SK_ColorBLUE, flags); + + if (fShowObject) { + canvas->drawPath(path, paint); + } else { + SkPaint strokePaint; + + strokePaint.setColor(paint.getColor()); + strokePaint.setStyle(SkPaint::kStroke_Style); + + canvas->drawPath(path, strokePaint); + } + } + + void onDrawContent(SkCanvas* canvas) override { + this->drawBG(canvas); + + static constexpr int kW = 800; + static constexpr SkScalar kPad = 15.f; + static constexpr SkPoint3 kLightPos = { 250, 400, 500 }; + static constexpr SkScalar kLightR = 100.f; + static constexpr SkScalar kHeight = 50.f; + static constexpr SkScalar kAmbientAlpha = 0.5f; + static constexpr SkScalar kSpotAlpha = 0.5f; + + canvas->translate(3 * kPad, 3 * kPad); + canvas->save(); + SkScalar x = 0; + SkScalar dy = 0; + SkTDArray<SkMatrix> matrices; + matrices.push()->reset(); + SkMatrix* m = matrices.push(); + m->setRotate(33.f, 25.f, 25.f); + m->postScale(1.2f, 0.8f, 25.f, 25.f); + SkPaint paint; + paint.setColor(SK_ColorGREEN); + paint.setAntiAlias(true); + SkScalar zValue = SkTMax(1.0f, kHeight + fZDelta); + std::function<SkScalar(SkScalar, SkScalar)> zFunc = + [zValue](SkScalar, SkScalar) { return zValue; }; + for (auto& m : matrices) { + for (auto flags : { kNone_ShadowFlag, kTransparentOccluder_ShadowFlag }) { + for (const auto& path : fPaths) { + SkRect postMBounds = path.getBounds(); + m.mapRect(&postMBounds); + SkScalar w = postMBounds.width() + kHeight; + SkScalar dx = w + kPad; + if (x + dx > kW - 3 * kPad) { + canvas->restore(); + canvas->translate(0, dy); + canvas->save(); + x = 0; + dy = 0; + } + + canvas->save(); + canvas->concat(m); + drawShadowedPath(canvas, path, zFunc, paint, kAmbientAlpha, kLightPos, kLightR, + kSpotAlpha, flags); + canvas->restore(); + + canvas->translate(dx, 0); + x += dx; + dy = SkTMax(dy, postMBounds.height() + kPad + kHeight); + } + } + } + // Show where the light is in x,y as a circle (specified in device space). + SkMatrix invCanvasM = canvas->getTotalMatrix(); + if (invCanvasM.invert(&invCanvasM)) { + canvas->save(); + canvas->concat(invCanvasM); + SkPaint paint; + paint.setColor(SK_ColorBLACK); + paint.setAntiAlias(true); + canvas->drawCircle(kLightPos.fX, kLightPos.fY, kLightR / 10.f, paint); + canvas->restore(); + } + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new ShadowUtilsView; } +static SkViewRegister reg(MyFactory); diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 5854451a41..7cf8cd8825 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -84,7 +84,12 @@ static bool on_mouse_handler(int x, int y, Window::InputState state, uint32_t mo } else if (Window::kUp_InputState == state) { io.MouseDown[0] = false; } - return true; + if (io.WantCaptureMouse) { + return true; + } else { + Viewer* viewer = reinterpret_cast<Viewer*>(userData); + return viewer->onMouse(x, y, state, modifiers); + } } static bool on_mouse_wheel_handler(float delta, uint32_t modifiers, void* userData) { @@ -867,6 +872,27 @@ bool Viewer::onTouch(intptr_t owner, Window::InputState state, float x, float y) return true; } +bool Viewer::onMouse(float x, float y, Window::InputState state, uint32_t modifiers) { + + SkPoint touchPoint = fDefaultMatrixInv.mapXY(x, y); + switch (state) { + case Window::kUp_InputState: { + fGesture.touchEnd(nullptr); + break; + } + case Window::kDown_InputState: { + fGesture.touchBegin(nullptr, touchPoint.fX, touchPoint.fY); + break; + } + case Window::kMove_InputState: { + fGesture.touchMoved(nullptr, touchPoint.fX, touchPoint.fY); + break; + } + } + fWindow->inval(); + return true; +} + void Viewer::drawStats(SkCanvas* canvas) { static const float kPixelPerMS = 2.0f; static const int kDisplayWidth = 130; diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h index c50f75073b..09a8946ac9 100644 --- a/tools/viewer/Viewer.h +++ b/tools/viewer/Viewer.h @@ -27,6 +27,7 @@ public: void onPaint(SkCanvas* canvas); void onIdle() override; bool onTouch(intptr_t owner, sk_app::Window::InputState state, float x, float y); + bool onMouse(float x, float y, sk_app::Window::InputState state, uint32_t modifiers); void onUIStateChanged(const SkString& stateName, const SkString& stateValue); bool onKey(sk_app::Window::Key key, sk_app::Window::InputState state, uint32_t modifiers); bool onChar(SkUnichar c, uint32_t modifiers); |