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 |