blob: fb5ba954637a683ea4dc765ad93ffb6083216643 [file] [log] [blame]
Brian Osman84d884a2021-01-29 16:35:45 -05001/*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm/gm.h"
9
10#if !defined(SK_BUILD_FOR_GOOGLE3) // Google3 doesn't build particles module
11
12#include "include/core/SkCanvas.h"
13#include "include/core/SkColor.h"
14#include "modules/particles/include/SkParticleEffect.h"
15#include "modules/particles/include/SkParticleSerialization.h"
16#include "modules/skresources/include/SkResources.h"
Brian Osman4d76f632021-01-21 11:47:12 -050017#include "src/sksl/SkSLVMGenerator.h"
Brian Osman84d884a2021-01-29 16:35:45 -050018#include "tools/Resources.h"
19
Brian Osman4d76f632021-01-21 11:47:12 -050020struct UniformValue {
21 const char* fName;
22 std::vector<float> fData;
23};
24
Brian Osman84d884a2021-01-29 16:35:45 -050025class ParticlesGM : public skiagm::GM {
26public:
Brian Osman4d76f632021-01-21 11:47:12 -050027 ParticlesGM(const char* name,
28 double startTime,
29 SkISize size,
30 SkPoint origin,
31 std::vector<UniformValue> uniforms = {})
32 : GM(SK_ColorBLACK)
33 , fName(name)
34 , fStartTime(startTime)
35 , fSize(size)
36 , fOrigin(origin)
37 , fUniforms(std::move(uniforms)) {}
Brian Osman84d884a2021-01-29 16:35:45 -050038
39 SkString onShortName() override { return SkStringPrintf("particles_%s", fName); }
40 SkISize onISize() override { return fSize; }
41
42 void onOnceBeforeDraw() override {
43 SkParticleEffect::RegisterParticleTypes();
44
45 auto jsonData = GetResourceAsData(SkStringPrintf("particles/%s.json", fName).c_str());
46 skjson::DOM dom(static_cast<const char*>(jsonData->data()), jsonData->size());
47 SkFromJsonVisitor fromJson(dom.root());
48
49 auto resourceProvider = skresources::FileResourceProvider::Make(GetResourcePath());
50 auto effectParams = sk_make_sp<SkParticleEffectParams>();
51 effectParams->visitFields(&fromJson);
52 effectParams->prepare(resourceProvider.get());
53
54 fEffect = sk_make_sp<SkParticleEffect>(effectParams);
Brian Osman4d76f632021-01-21 11:47:12 -050055 for (const auto& val : fUniforms) {
56 SkAssertResult(fEffect->setUniform(val.fName, val.fData.data(), val.fData.size()));
57 }
58
Brian Osman84d884a2021-01-29 16:35:45 -050059 fEffect->start(/*now=*/0.0, /*looping=*/true);
60
61 // Fast-forward (in 30 fps time-slices) to the requested time
62 for (double time = 0; time < fStartTime; time += 1.0 / 30) {
63 fEffect->update(/*now=*/std::min(time, fStartTime));
64 }
65 }
66
67 bool onAnimate(double nanos) override {
68 if (fEffect) {
69 fEffect->update(fStartTime + (nanos * 1E-9));
70 }
71 return true;
72 }
73
74 void onDraw(SkCanvas* canvas) override {
75 canvas->save();
76 canvas->translate(fOrigin.fX, fOrigin.fY);
77 fEffect->draw(canvas);
78 canvas->restore();
79 }
80
81protected:
Brian Osman4d76f632021-01-21 11:47:12 -050082 const char* fName;
83 const double fStartTime;
84 const SkISize fSize;
85 const SkPoint fOrigin;
86 sk_sp<SkParticleEffect> fEffect;
87 std::vector<UniformValue> fUniforms;
Brian Osman84d884a2021-01-29 16:35:45 -050088};
89
90DEF_GM(return new ParticlesGM("confetti", 1.0, {400, 400}, {200, 200});)
91DEF_GM(return new ParticlesGM("cube", 1.0, {400, 400}, {200, 200});)
92DEF_GM(return new ParticlesGM("curves", 4.0, {100, 200}, { 50, 190});)
93DEF_GM(return new ParticlesGM("mandrill", 1.0, {250, 250}, { 25, 25});)
94DEF_GM(return new ParticlesGM("spiral", 2.0, {250, 250}, {125, 125});)
95DEF_GM(return new ParticlesGM("sprite_frame", 1.0, {200, 200}, {100, 100});)
96DEF_GM(return new ParticlesGM("text", 1.0, {250, 110}, { 10, 100});)
Brian Osman4d76f632021-01-21 11:47:12 -050097DEF_GM(return new ParticlesGM("uniforms", 2.0, {250, 250}, {125, 125},
98 {{"rate", {2.0f}},
99 {"spin", {4.0f}},
100 {"color", {0.25f, 0.75f, 0.75f}}});)
Brian Osman84d884a2021-01-29 16:35:45 -0500101
102#endif // SK_BUILD_FOR_GOOGLE3