Particles: SkImageBinding to allow sampling an image from script
Provides functionality similar to AE property maps Change-Id: I1705706a6b7e25fbab55465f2e20d0b145330b0b Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255977 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
9dac0d8216
commit
db2e7641be
@ -7,7 +7,9 @@
|
||||
|
||||
#include "modules/particles/include/SkParticleBinding.h"
|
||||
|
||||
#include "include/core/SkBitmap.h"
|
||||
#include "include/core/SkContourMeasure.h"
|
||||
#include "include/core/SkImage.h"
|
||||
#include "include/core/SkPath.h"
|
||||
#include "include/utils/SkParsePath.h"
|
||||
#include "include/utils/SkRandom.h"
|
||||
@ -193,6 +195,74 @@ private:
|
||||
SkPathContours fContours;
|
||||
};
|
||||
|
||||
// Exposes an SkBitmap as an external, callable value. p(xy) returns a float4
|
||||
class SkBitmapExternalValue : public SkParticleExternalValue {
|
||||
public:
|
||||
SkBitmapExternalValue(const char* name, SkSL::Compiler& compiler, const SkBitmap& bitmap)
|
||||
: SkParticleExternalValue(name, compiler, *compiler.context().fFloat4_Type)
|
||||
, fBitmap(bitmap) {
|
||||
SkASSERT(bitmap.colorType() == kRGBA_F32_SkColorType);
|
||||
}
|
||||
|
||||
bool canCall() const override { return true; }
|
||||
int callParameterCount() const override { return 1; }
|
||||
void getCallParameterTypes(const SkSL::Type** outTypes) const override {
|
||||
outTypes[0] = fCompiler.context().fFloat2_Type.get();
|
||||
}
|
||||
|
||||
void call(int index, float* arguments, float* outReturn) override {
|
||||
int x = SkTPin(static_cast<int>(arguments[0] * fBitmap.width()), 0, fBitmap.width() - 1);
|
||||
int y = SkTPin(static_cast<int>(arguments[1] * fBitmap.height()), 0, fBitmap.height() - 1);
|
||||
float* p = static_cast<float*>(fBitmap.getAddr(x, y));
|
||||
memcpy(outReturn, p, 4 * sizeof(float));
|
||||
}
|
||||
|
||||
private:
|
||||
SkBitmap fBitmap;
|
||||
};
|
||||
|
||||
class SkImageBinding : public SkParticleBinding {
|
||||
public:
|
||||
SkImageBinding(const char* name = "", const char* imagePath = "", const char* imageName = "")
|
||||
: SkParticleBinding(name)
|
||||
, fImagePath(imagePath)
|
||||
, fImageName(imageName) {}
|
||||
|
||||
REFLECTED(SkImageBinding, SkParticleBinding)
|
||||
|
||||
void visitFields(SkFieldVisitor* v) override {
|
||||
SkParticleBinding::visitFields(v);
|
||||
v->visit("ImagePath", fImagePath);
|
||||
v->visit("ImageName", fImageName);
|
||||
}
|
||||
|
||||
std::unique_ptr<SkParticleExternalValue> toValue(SkSL::Compiler& compiler) override {
|
||||
return std::unique_ptr<SkParticleExternalValue>(
|
||||
new SkBitmapExternalValue(fName.c_str(), compiler, fBitmap));
|
||||
}
|
||||
|
||||
void prepare(const skresources::ResourceProvider* resourceProvider) override {
|
||||
if (auto asset = resourceProvider->loadImageAsset(fImagePath.c_str(), fImageName.c_str(),
|
||||
nullptr)) {
|
||||
if (auto image = asset->getFrame(0)) {
|
||||
fBitmap.allocPixels(image->imageInfo().makeColorType(kRGBA_F32_SkColorType));
|
||||
image->readPixels(fBitmap.pixmap(), 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fBitmap.allocPixels(SkImageInfo::Make(1, 1, kRGBA_F32_SkColorType, kPremul_SkAlphaType));
|
||||
fBitmap.eraseColor(SK_ColorWHITE);
|
||||
}
|
||||
|
||||
private:
|
||||
SkString fImagePath;
|
||||
SkString fImageName;
|
||||
|
||||
// Cached
|
||||
SkBitmap fBitmap;
|
||||
};
|
||||
|
||||
sk_sp<SkParticleBinding> SkParticleBinding::MakeEffectBinding(
|
||||
const char* name, sk_sp<SkParticleEffectParams> params) {
|
||||
return sk_sp<SkParticleBinding>(new SkEffectBinding(name, params));
|
||||
@ -205,6 +275,7 @@ sk_sp<SkParticleBinding> SkParticleBinding::MakePathBinding(const char* name, co
|
||||
void SkParticleBinding::RegisterBindingTypes() {
|
||||
REGISTER_REFLECTED(SkParticleBinding);
|
||||
REGISTER_REFLECTED(SkEffectBinding);
|
||||
REGISTER_REFLECTED(SkImageBinding);
|
||||
REGISTER_REFLECTED(SkPathBinding);
|
||||
REGISTER_REFLECTED(SkTextBinding);
|
||||
}
|
||||
|
38
resources/particles/mandrill.json
Normal file
38
resources/particles/mandrill.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"MaxCount": 4000,
|
||||
"Drawable": {
|
||||
"Type": "SkCircleDrawable",
|
||||
"Radius": 3
|
||||
},
|
||||
"EffectCode": [
|
||||
"void effectSpawn(inout Effect effect) {",
|
||||
" effect.rate = 4000;",
|
||||
"}",
|
||||
"",
|
||||
"void effectUpdate(inout Effect effect) {",
|
||||
"}",
|
||||
""
|
||||
],
|
||||
"Code": [
|
||||
"void spawn(inout Particle p) {",
|
||||
" p.lifetime = 1;",
|
||||
" p.pos = float2(rand, rand) * 200;",
|
||||
" p.vel = float2(rand, rand) * 2 - 1;",
|
||||
" p.vel *= 20;",
|
||||
" p.scale = mix(0.25, 1, rand);",
|
||||
"}",
|
||||
"",
|
||||
"void update(inout Particle p) {",
|
||||
" p.color = img(p.pos / 200);",
|
||||
"}",
|
||||
""
|
||||
],
|
||||
"Bindings": [
|
||||
{
|
||||
"Type": "SkImageBinding",
|
||||
"Name": "img",
|
||||
"ImagePath": "images",
|
||||
"ImageName": "mandrill_128.png"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user