103 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright 2021 Google LLC
 | |
|  *
 | |
|  * Use of this source code is governed by a BSD-style license that can be
 | |
|  * found in the LICENSE file.
 | |
|  */
 | |
| 
 | |
| #include "gm/gm.h"
 | |
| 
 | |
| #if !defined(SK_BUILD_FOR_GOOGLE3)  // Google3 doesn't build particles module
 | |
| 
 | |
| #include "include/core/SkCanvas.h"
 | |
| #include "include/core/SkColor.h"
 | |
| #include "modules/particles/include/SkParticleEffect.h"
 | |
| #include "modules/particles/include/SkParticleSerialization.h"
 | |
| #include "modules/skresources/include/SkResources.h"
 | |
| #include "src/sksl/codegen/SkSLVMCodeGenerator.h"
 | |
| #include "tools/Resources.h"
 | |
| 
 | |
| struct UniformValue {
 | |
|     const char*        fName;
 | |
|     std::vector<float> fData;
 | |
| };
 | |
| 
 | |
| class ParticlesGM : public skiagm::GM {
 | |
| public:
 | |
|     ParticlesGM(const char* name,
 | |
|                 double startTime,
 | |
|                 SkISize size,
 | |
|                 SkPoint origin,
 | |
|                 std::vector<UniformValue> uniforms = {})
 | |
|             : GM(SK_ColorBLACK)
 | |
|             , fName(name)
 | |
|             , fStartTime(startTime)
 | |
|             , fSize(size)
 | |
|             , fOrigin(origin)
 | |
|             , fUniforms(std::move(uniforms)) {}
 | |
| 
 | |
|     SkString onShortName() override { return SkStringPrintf("particles_%s", fName); }
 | |
|     SkISize onISize() override { return fSize; }
 | |
| 
 | |
|     void onOnceBeforeDraw() override {
 | |
|         SkParticleEffect::RegisterParticleTypes();
 | |
| 
 | |
|         auto jsonData = GetResourceAsData(SkStringPrintf("particles/%s.json", fName).c_str());
 | |
|         skjson::DOM dom(static_cast<const char*>(jsonData->data()), jsonData->size());
 | |
|         SkFromJsonVisitor fromJson(dom.root());
 | |
| 
 | |
|         auto resourceProvider = skresources::FileResourceProvider::Make(GetResourcePath());
 | |
|         auto effectParams = sk_make_sp<SkParticleEffectParams>();
 | |
|         effectParams->visitFields(&fromJson);
 | |
|         effectParams->prepare(resourceProvider.get());
 | |
| 
 | |
|         fEffect = sk_make_sp<SkParticleEffect>(effectParams);
 | |
|         for (const auto& val : fUniforms) {
 | |
|             SkAssertResult(fEffect->setUniform(val.fName, val.fData.data(), val.fData.size()));
 | |
|         }
 | |
| 
 | |
|         fEffect->start(/*now=*/0.0, /*looping=*/true);
 | |
| 
 | |
|         // Fast-forward (in 30 fps time-slices) to the requested time
 | |
|         for (double time = 0; time < fStartTime; time += 1.0 / 30) {
 | |
|             fEffect->update(/*now=*/std::min(time, fStartTime));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     bool onAnimate(double nanos) override {
 | |
|         if (fEffect) {
 | |
|             fEffect->update(fStartTime + (nanos * 1E-9));
 | |
|         }
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     void onDraw(SkCanvas* canvas) override {
 | |
|         canvas->save();
 | |
|         canvas->translate(fOrigin.fX, fOrigin.fY);
 | |
|         fEffect->draw(canvas);
 | |
|         canvas->restore();
 | |
|     }
 | |
| 
 | |
| protected:
 | |
|     const char*               fName;
 | |
|     const double              fStartTime;
 | |
|     const SkISize             fSize;
 | |
|     const SkPoint             fOrigin;
 | |
|     sk_sp<SkParticleEffect>   fEffect;
 | |
|     std::vector<UniformValue> fUniforms;
 | |
| };
 | |
| 
 | |
| DEF_GM(return new ParticlesGM("confetti",     1.0, {400, 400}, {200, 200});)
 | |
| DEF_GM(return new ParticlesGM("cube",         1.0, {400, 400}, {200, 200});)
 | |
| DEF_GM(return new ParticlesGM("curves",       4.0, {100, 200}, { 50, 190});)
 | |
| DEF_GM(return new ParticlesGM("mandrill",     1.0, {250, 250}, { 25,  25});)
 | |
| DEF_GM(return new ParticlesGM("spiral",       2.0, {250, 250}, {125, 125});)
 | |
| DEF_GM(return new ParticlesGM("sprite_frame", 1.0, {200, 200}, {100, 100});)
 | |
| DEF_GM(return new ParticlesGM("text",         1.0, {250, 110}, { 10, 100});)
 | |
| DEF_GM(return new ParticlesGM("uniforms",     2.0, {250, 250}, {125, 125},
 | |
|                                               {{"rate",  {2.0f}},
 | |
|                                                {"spin",  {4.0f}},
 | |
|                                                {"color", {0.25f, 0.75f, 0.75f}}});)
 | |
| 
 | |
| #endif  // SK_BUILD_FOR_GOOGLE3
 |