Chromium Code Reviews| Index: gm/victor-shadows.cpp |
| diff --git a/gm/victor-shadows.cpp b/gm/victor-shadows.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..835a24300ca3f0cdd09a6bf675a841441227714d |
| --- /dev/null |
| +++ b/gm/victor-shadows.cpp |
| @@ -0,0 +1,182 @@ |
| +/* |
| + * 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 "gm.h" |
| +#include "SkDrawFilter.h" |
| +#include "SkLights.h" |
| +#include "SkLightingShader.h" |
| +#include "SkPictureRecorder.h" |
| +#include "SkSurface.h" |
| + |
| + |
| +sk_sp<SkShader> make_lighting_shader(const SkMatrix& ctm, sk_sp<SkLights> lights) { |
| + // TODO: Victor figures this out |
| +#if 0 |
| + // TODO: correctly pull out the pure rotation |
| + SkVector invNormRotation = { ctm[SkMatrix::kMScaleX], ctm[SkMatrix::kMSkewY] }; |
| + |
| + return SkLightingShader::Make(nullptr, |
| + nullptr, |
| + std::move(lights), |
| + invNormRotation, |
| + nullptr, |
| + nullptr); |
| +#else |
| + return nullptr; |
| +#endif |
| +} |
| + |
| +sk_sp<SkPicture> make_picture(int width, int height, sk_sp<SkLights> lights) { |
| + SkPictureRecorder recorder; |
| + |
| + // eventually add SkBBHFactory (bounding box factory) |
| + SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(width, height)); |
| + |
| + SkASSERT(canvas->getTotalMatrix().isIdentity()); |
| + sk_sp<SkShader> identityLights(make_lighting_shader(canvas->getTotalMatrix(), lights)); |
| + SkPaint paint; |
| + paint.setShader(identityLights); |
| + paint.setColor(SK_ColorWHITE); |
| + |
| + // LONG RANGE TODO: tag occluders |
| + // LONG RANGE TODO: track number of IDs we need (hopefully less than 256) |
| + // and determinate the mapping from z to id |
| + |
| + // universal receiver, "ground" |
| + canvas->drawRect(SkRect::MakeIWH(width, height), paint); |
| + |
| + // Maybe add the ID here along with the depth |
|
robertphillips
2016/07/01 15:17:54
Note that you're also going to need to add a SkCan
|
| + // canvas->setZ(10); |
| + |
| + canvas->save(); |
| + canvas->translate(50, 50); |
| + canvas->clipRect(SkRect::MakeLTRB(475, 475, 525, 525)); |
| + |
| + // Add an assert that Z order matches painter's order |
| + /// |
| + // canvas->setZ(20); |
| + |
| + SkASSERT(!canvas->getTotalMatrix().isIdentity()); |
| + paint.setShader(make_lighting_shader(canvas->getTotalMatrix(), lights)); |
| + paint.setColor(SK_ColorBLUE); |
| + |
| + // use an IDE |
| + canvas->drawRect(SkRect::MakeLTRB(0, 0, 1000, 1000), paint); |
| + canvas->restore(); |
| + |
| + // TODO: think about if the Z-order always matching painting order is too strict |
| + SkASSERT(canvas->getTotalMatrix().isIdentity()); |
| + paint.setShader(identityLights); |
| + paint.setColor(SK_ColorRED); |
| + canvas->drawRect(SkRect::MakeLTRB(700, 700, 710, 710), paint); |
| + |
| + return recorder.finishRecordingAsPicture(); |
| +} |
| + |
| +namespace skiagm { |
| + |
|
robertphillips
2016/07/01 15:17:54
Thinking about this a bit more I think we should u
jvanverth1
2016/07/01 15:31:04
After talking to Robert about this, when we create
|
| +class SkFoo : public SkDrawFilter { |
| +public: |
| + SkFoo(/*SkTDynamicHash<int, int> *hash*/) { |
| + |
| + } |
| + |
| + bool filter(SkPaint* paint, Type) override { |
| + SkPaint newPaint; |
| + |
| + SkColor color = 0xFF000000; |
| + |
| + color |= 0x000000AA; // Put the index into the blue component |
| + newPaint.setColor(color); |
| + // Map the individual draw to a specific index |
| + *paint = newPaint; |
| + return true; |
| + } |
| +}; |
| + |
| +// This GM ... |
| +class Shadows1GM : public GM { |
| +public: |
| + Shadows1GM() { |
| + this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); |
| + |
| + 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))); |
| + |
| + fLights = builder.finish(); |
| + } |
| + |
| +protected: |
| + static const int kWidth = 1024; |
| + static const int kHeight = 1024; |
| + |
| + |
| + SkString onShortName() override { |
| + return SkString("victor-shadows"); |
| + } |
| + |
| + SkISize onISize() override { |
| + return SkISize::Make(kWidth, kHeight); |
| + } |
| + |
| + void onDraw(SkCanvas* canvas) override { |
| + |
| + sk_sp<SkPicture> pic(make_picture(kWidth, kHeight, fLights)); |
| + |
| + sk_sp<SkDrawFilter> filter(new SkFoo()); |
| + |
| + sk_sp<SkImage> img; |
| + for (int i = 0; i < fLights->numLights(); ++i) { |
| + if (SkLights::Light::kAmbient_LightType == fLights->light(i).type()) { |
| + continue; |
| + } |
| + |
| + // generate shadow map |
| + |
| + // TODO: compute the correct size of the shadow map from the light properties |
| + // TODO: maybe add a kDepth_8_SkColorType |
| + // TODO: change to kIndex_8_SkColorType |
|
robertphillips
2016/07/01 15:17:55
We could probably start off with this being kAlpha
|
| + SkImageInfo info = SkImageInfo::Make(256, 256, kBGRA_8888_SkColorType, kOpaque_SkAlphaType); |
| + |
| + sk_sp<SkSurface> surf(canvas->makeSurface(info)); |
| + SkCanvas* shadowMapCanvas = surf->getCanvas(); |
| + |
| + // TODO: add a matrix to map the scene to the viewpoint of the light |
| + fLights->light(i); |
| + |
| + SkMatrix mat; |
| + mat.setRectToRect(SkRect::MakeIWH(kWidth, kHeight), SkRect::MakeIWH(256, 256), |
| + SkMatrix::kFill_ScaleToFit); |
| + |
| + shadowMapCanvas->setMatrix(mat); |
| + shadowMapCanvas->setDrawFilter(filter.get()); |
| + shadowMapCanvas->drawPicture(pic); |
| + |
| + img = surf->makeImageSnapshot(); |
| + |
| + // TODO: Add something like this |
| + fLights->light(i).setShadowMap(img); |
| + } |
| + |
| + // perform final pass |
| + canvas->drawPicture(std::move(pic)); |
| + //canvas->drawImage(img, 0, 0); |
| + } |
| + |
| +private: |
| + sk_sp<SkLights> fLights; |
| + |
| + typedef GM INHERITED; |
| +}; |
| + |
| +////////////////////////////////////////////////////////////////////////////// |
| + |
| +DEF_GM(return new Shadows1GM;) |
| +} |