| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 | 8 |
| 9 #include "gm.h" | 9 #include "gm.h" |
| 10 #include "SkPathEffect.h" | 10 #include "SkPathEffect.h" |
| 11 #include "SkPictureRecorder.h" | 11 #include "SkPictureRecorder.h" |
| 12 #include "SkShadowPaintFilterCanvas.h" | 12 #include "SkShadowPaintFilterCanvas.h" |
| 13 #include "SkShadowShader.h" | 13 #include "SkShadowShader.h" |
| 14 #include "SkSurface.h" | 14 #include "SkSurface.h" |
| 15 | 15 |
| 16 #ifdef SK_EXPERIMENTAL_SHADOWING | 16 #ifdef SK_EXPERIMENTAL_SHADOWING |
| 17 | 17 |
| 18 static sk_sp<SkShader> make_shadow_shader(sk_sp<SkImage> povDepth, | |
| 19 sk_sp<SkImage> diffuse, | |
| 20 sk_sp<SkLights> lights) { | |
| 21 | |
| 22 sk_sp<SkShader> povDepthShader = povDepth->makeShader(SkShader::kClamp_TileM
ode, | |
| 23 SkShader::kClamp_TileM
ode); | |
| 24 | |
| 25 sk_sp<SkShader> diffuseShader = diffuse->makeShader(SkShader::kClamp_TileMod
e, | |
| 26 SkShader::kClamp_TileMod
e); | |
| 27 | |
| 28 return SkShadowShader::Make(std::move(povDepthShader), | |
| 29 std::move(diffuseShader), | |
| 30 std::move(lights), | |
| 31 diffuse->width(), diffuse->height()); | |
| 32 } | |
| 33 | 18 |
| 34 static sk_sp<SkPicture> make_test_picture(int width, int height) { | 19 static sk_sp<SkPicture> make_test_picture(int width, int height) { |
| 35 SkPictureRecorder recorder; | 20 SkPictureRecorder recorder; |
| 36 | 21 |
| 37 // LONG RANGE TODO: eventually add SkBBHFactory (bounding box factory) | 22 // LONG RANGE TODO: eventually add SkBBHFactory (bounding box factory) |
| 38 SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(width, height)); | 23 SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(width, height)); |
| 39 | 24 |
| 40 SkASSERT(canvas->getTotalMatrix().isIdentity()); | 25 SkASSERT(canvas->getTotalMatrix().isIdentity()); |
| 41 SkPaint paint; | 26 SkPaint paint; |
| 42 paint.setColor(SK_ColorGRAY); | 27 paint.setColor(SK_ColorGRAY); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 } | 87 } |
| 103 | 88 |
| 104 SkISize onISize() override { | 89 SkISize onISize() override { |
| 105 return SkISize::Make(kWidth, kHeight); | 90 return SkISize::Make(kWidth, kHeight); |
| 106 } | 91 } |
| 107 | 92 |
| 108 void onDraw(SkCanvas* canvas) override { | 93 void onDraw(SkCanvas* canvas) override { |
| 109 // This picture stores the picture of the scene. | 94 // This picture stores the picture of the scene. |
| 110 // It's used to generate the depth maps. | 95 // It's used to generate the depth maps. |
| 111 sk_sp<SkPicture> pic(make_test_picture(kWidth, kHeight)); | 96 sk_sp<SkPicture> pic(make_test_picture(kWidth, kHeight)); |
| 112 | 97 canvas->setLights(fLights); |
| 113 for (int i = 0; i < fLights->numLights(); ++i) { | 98 canvas->drawShadowedPicture(pic, nullptr, nullptr); |
| 114 // skip over ambient lights; they don't cast shadows | |
| 115 if (SkLights::Light::kAmbient_LightType == fLights->light(i).type())
{ | |
| 116 continue; | |
| 117 } | |
| 118 // TODO: compute the correct size of the depth map from the light pr
operties | |
| 119 // TODO: maybe add a kDepth_8_SkColorType | |
| 120 | |
| 121 // TODO: find actual max depth of picture | |
| 122 SkISize shMapSize = SkShadowPaintFilterCanvas:: | |
| 123 ComputeDepthMapSize(fLights->light(i), 255, kWidth, kHeight)
; | |
| 124 | |
| 125 SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHe
ight, | |
| 126 kBGRA_8888_SkColorType, | |
| 127 kOpaque_SkAlphaType); | |
| 128 | |
| 129 // Create a new surface (that matches the backend of canvas) | |
| 130 // for each shadow map | |
| 131 sk_sp<SkSurface> surf(canvas->makeSurface(info)); | |
| 132 | |
| 133 // Wrap another SPFCanvas around the surface | |
| 134 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = | |
| 135 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); | |
| 136 | |
| 137 // set the depth map canvas to have the light we're drawing. | |
| 138 SkLights::Builder builder; | |
| 139 builder.add(fLights->light(i)); | |
| 140 sk_sp<SkLights> curLight = builder.finish(); | |
| 141 | |
| 142 depthMapCanvas->setLights(std::move(curLight)); | |
| 143 depthMapCanvas->drawPicture(pic); | |
| 144 | |
| 145 fLights->light(i).setShadowMap(surf->makeImageSnapshot()); | |
| 146 } | |
| 147 | |
| 148 sk_sp<SkImage> povDepthMap; | |
| 149 sk_sp<SkImage> diffuseMap; | |
| 150 | |
| 151 // TODO: pass the depth to the shader in vertices, or uniforms | |
| 152 // so we don't have to render depth and color separately | |
| 153 | |
| 154 // povDepthMap | |
| 155 { | |
| 156 SkLights::Builder builder; | |
| 157 builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f), | |
| 158 SkVector3::Make(0.0f, 0.0f, 1.0f))); | |
| 159 sk_sp<SkLights> povLight = builder.finish(); | |
| 160 | |
| 161 SkImageInfo info = SkImageInfo::Make(kWidth, kHeight, | |
| 162 kBGRA_8888_SkColorType, | |
| 163 kOpaque_SkAlphaType); | |
| 164 | |
| 165 // Create a new surface (that matches the backend of canvas) | |
| 166 // to create the povDepthMap | |
| 167 sk_sp<SkSurface> surf(canvas->makeSurface(info)); | |
| 168 | |
| 169 // Wrap another SPFCanvas around the surface | |
| 170 sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = | |
| 171 sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); | |
| 172 | |
| 173 // set the depth map canvas to have the light as the user's POV | |
| 174 depthMapCanvas->setLights(std::move(povLight)); | |
| 175 | |
| 176 depthMapCanvas->drawPicture(pic); | |
| 177 | |
| 178 povDepthMap = surf->makeImageSnapshot(); | |
| 179 } | |
| 180 | |
| 181 // diffuseMap | |
| 182 { | |
| 183 SkImageInfo info = SkImageInfo::Make(kWidth, kHeight, | |
| 184 kBGRA_8888_SkColorType, | |
| 185 kOpaque_SkAlphaType); | |
| 186 | |
| 187 sk_sp<SkSurface> surf(canvas->makeSurface(info)); | |
| 188 surf->getCanvas()->drawPicture(pic); | |
| 189 | |
| 190 diffuseMap = surf->makeImageSnapshot(); | |
| 191 } | |
| 192 | |
| 193 SkPaint paint; | |
| 194 paint.setShader(make_shadow_shader(std::move(povDepthMap), std::move(dif
fuseMap), fLights)); | |
| 195 | |
| 196 canvas->drawRect(SkRect::MakeIWH(kWidth, kHeight), paint); | |
| 197 } | 99 } |
| 198 | 100 |
| 199 private: | 101 private: |
| 200 sk_sp<SkLights> fLights; | 102 sk_sp<SkLights> fLights; |
| 201 | |
| 202 typedef GM INHERITED; | 103 typedef GM INHERITED; |
| 203 }; | 104 }; |
| 204 | 105 |
| 205 ////////////////////////////////////////////////////////////////////////////// | 106 ////////////////////////////////////////////////////////////////////////////// |
| 206 | 107 |
| 207 DEF_GM(return new ShadowMapsGM;) | 108 DEF_GM(return new ShadowMapsGM;) |
| 208 } | 109 } |
| 209 | 110 |
| 210 #endif | 111 #endif |
| OLD | NEW |