Brian Osman | 84d884a | 2021-01-29 16:35:45 -0500 | [diff] [blame] | 1 | /* |
| 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 Osman | 4d76f63 | 2021-01-21 11:47:12 -0500 | [diff] [blame] | 17 | #include "src/sksl/SkSLVMGenerator.h" |
Brian Osman | 84d884a | 2021-01-29 16:35:45 -0500 | [diff] [blame] | 18 | #include "tools/Resources.h" |
| 19 | |
Brian Osman | 4d76f63 | 2021-01-21 11:47:12 -0500 | [diff] [blame] | 20 | struct UniformValue { |
| 21 | const char* fName; |
| 22 | std::vector<float> fData; |
| 23 | }; |
| 24 | |
Brian Osman | 84d884a | 2021-01-29 16:35:45 -0500 | [diff] [blame] | 25 | class ParticlesGM : public skiagm::GM { |
| 26 | public: |
Brian Osman | 4d76f63 | 2021-01-21 11:47:12 -0500 | [diff] [blame] | 27 | 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 Osman | 84d884a | 2021-01-29 16:35:45 -0500 | [diff] [blame] | 38 | |
| 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 Osman | 4d76f63 | 2021-01-21 11:47:12 -0500 | [diff] [blame] | 55 | for (const auto& val : fUniforms) { |
| 56 | SkAssertResult(fEffect->setUniform(val.fName, val.fData.data(), val.fData.size())); |
| 57 | } |
| 58 | |
Brian Osman | 84d884a | 2021-01-29 16:35:45 -0500 | [diff] [blame] | 59 | 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 | |
| 81 | protected: |
Brian Osman | 4d76f63 | 2021-01-21 11:47:12 -0500 | [diff] [blame] | 82 | 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 Osman | 84d884a | 2021-01-29 16:35:45 -0500 | [diff] [blame] | 88 | }; |
| 89 | |
| 90 | DEF_GM(return new ParticlesGM("confetti", 1.0, {400, 400}, {200, 200});) |
| 91 | DEF_GM(return new ParticlesGM("cube", 1.0, {400, 400}, {200, 200});) |
| 92 | DEF_GM(return new ParticlesGM("curves", 4.0, {100, 200}, { 50, 190});) |
| 93 | DEF_GM(return new ParticlesGM("mandrill", 1.0, {250, 250}, { 25, 25});) |
| 94 | DEF_GM(return new ParticlesGM("spiral", 2.0, {250, 250}, {125, 125});) |
| 95 | DEF_GM(return new ParticlesGM("sprite_frame", 1.0, {200, 200}, {100, 100});) |
| 96 | DEF_GM(return new ParticlesGM("text", 1.0, {250, 110}, { 10, 100});) |
Brian Osman | 4d76f63 | 2021-01-21 11:47:12 -0500 | [diff] [blame] | 97 | DEF_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 Osman | 84d884a | 2021-01-29 16:35:45 -0500 | [diff] [blame] | 101 | |
| 102 | #endif // SK_BUILD_FOR_GOOGLE3 |