add skotties to cube demo
Change-Id: I2e1db9d4255cfcac4c589b726a371adfb0c5786e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271576
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
diff --git a/samplecode/Sample3D.cpp b/samplecode/Sample3D.cpp
index 0f17540..6c6116d 100644
--- a/samplecode/Sample3D.cpp
+++ b/samplecode/Sample3D.cpp
@@ -509,72 +509,34 @@
}
};
-class SampleBump3D : public Sample3DView {
+class SampleCubeBase : public Sample3DView {
enum {
DX = 400,
DY = 300
};
- SkRRect fRR;
- LightOnSphere fLight = {{200 + DX, 200 + DY}, 800, 12};
-
- VSphere fSphere;
-
- sk_sp<SkShader> fBmpShader, fImgShader;
- sk_sp<SkRuntimeEffect> fEffect;
-
SkM44 fWorldToClick,
fClickToWorld;
SkM44 fRotation, // part of model
fClickRotation; // temp during a click/drag
+protected:
+ enum Flags {
+ kCanRunOnCPU = 1 << 0,
+ kShowLightDome = 1 << 1,
+ };
+
+ LightOnSphere fLight = {{200 + DX, 200 + DY}, 800, 12};
+
+ VSphere fSphere;
+ Flags fFlags;
+
public:
- SampleBump3D() : fSphere({200 + DX, 200 + DY}, 400) {}
-
- SkString name() override { return SkString("bump3d"); }
-
- void onOnceBeforeDraw() override {
- fRR = SkRRect::MakeRectXY({20, 20, 380, 380}, 50, 50);
- auto img = GetResourceAsImage("images/brickwork-texture.jpg");
- fImgShader = img->makeShader(SkMatrix::MakeScale(2, 2));
- img = GetResourceAsImage("images/brickwork_normal-map.jpg");
- fBmpShader = img->makeShader(SkMatrix::MakeScale(2, 2));
-
- const char code[] = R"(
- in fragmentProcessor color_map;
- in fragmentProcessor normal_map;
-
- uniform float4x4 localToWorld;
- uniform float4x4 localToWorldAdjInv;
- uniform float3 lightPos;
-
- float3 convert_normal_sample(half4 c) {
- float3 n = 2 * c.rgb - 1;
- n.y = -n.y;
- return n;
- }
-
- void main(float2 p, inout half4 color) {
- float3 norm = convert_normal_sample(sample(normal_map, p));
- float3 plane_norm = normalize(localToWorld * float4(norm, 0)).xyz;
-
- float3 plane_pos = (localToWorld * float4(p, 0, 1)).xyz;
- float3 light_dir = normalize(lightPos - plane_pos);
-
- float ambient = 0.2;
- float dp = dot(plane_norm, light_dir);
- float scale = min(ambient + max(dp, 0), 1);
-
- color = sample(color_map, p) * half4(float4(scale, scale, scale, 1));
- }
- )";
- auto [effect, error] = SkRuntimeEffect::Make(SkString(code));
- if (!effect) {
- SkDebugf("runtime error %s\n", error.c_str());
- }
- fEffect = effect;
- }
+ SampleCubeBase(Flags flags)
+ : fSphere({200 + DX, 200 + DY}, 400)
+ , fFlags(flags)
+ {}
bool onChar(SkUnichar uni) override {
switch (uni) {
@@ -584,40 +546,7 @@
return this->Sample3DView::onChar(uni);
}
- void drawContent(SkCanvas* canvas, const SkM44& m, SkColor color) {
- SkM44 trans = SkM44::Translate(200, 200, 0); // center of the rotation
-
- canvas->experimental_concat44(trans * fRot * m * inv(trans));
-
- // wonder if the runtimeeffect can do this reject? (in a setup function)
- if (!front(canvas->experimental_getLocalToDevice())) {
- return;
- }
-
- auto adj_inv = [](const SkM44& m) {
- SkM44 inv;
- SkAssertResult(m.invert(&inv));
- return inv.transpose();
- };
-
- struct Uniforms {
- SkM44 fLocalToWorld;
- SkM44 fLocalToWorldAdjInv;
- SkV3 fLightPos;
- } uni;
- uni.fLocalToWorld = canvas->experimental_getLocalToWorld();
- uni.fLocalToWorldAdjInv = adj_inv(uni.fLocalToWorld);
- uni.fLightPos = fLight.computeWorldPos(fSphere);
-
- sk_sp<SkData> data = SkData::MakeWithCopy(&uni, sizeof(uni));
- sk_sp<SkShader> children[] = { fImgShader, fBmpShader };
-
- SkPaint paint;
- paint.setColor(color);
- paint.setShader(fEffect->makeShader(data, children, 2, nullptr, true));
-
- canvas->drawRRect(fRR, paint);
- }
+ virtual void drawContent(SkCanvas* canvas, SkColor, int index, bool drawFront) = 0;
void setClickToWorld(SkCanvas* canvas, const SkM44& clickM) {
auto l2d = canvas->experimental_getLocalToDevice();
@@ -626,7 +555,7 @@
}
void onDrawContent(SkCanvas* canvas) override {
- if (canvas->getGrContext() == nullptr) {
+ if (!canvas->getGrContext() && !(fFlags & kCanRunOnCPU)) {
return;
}
SkM44 clickM = canvas->experimental_getLocalToDevice();
@@ -638,16 +567,25 @@
this->setClickToWorld(canvas, clickM);
- for (auto f : faces) {
- SkAutoCanvasRestore acr(canvas, true);
- this->drawContent(canvas, fClickRotation * fRotation * f.asM44(200), f.fColor);
+ for (bool drawFront : {false, true}) {
+ int index = 0;
+ for (auto f : faces) {
+ SkAutoCanvasRestore acr(canvas, true);
+
+ SkM44 trans = SkM44::Translate(200, 200, 0); // center of the rotation
+ SkM44 m = fClickRotation * fRotation * f.asM44(200);
+
+ canvas->experimental_concat44(trans * fRot * m * inv(trans));
+ this->drawContent(canvas, f.fColor, index++, drawFront);
+ }
}
canvas->restore(); // camera
canvas->restore(); // center the content in the window
- fLight.draw(canvas);
- {
+ if (fFlags & kShowLightDome){
+ fLight.draw(canvas);
+
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
@@ -697,4 +635,137 @@
return true;
}
};
+
+class SampleBump3D : public SampleCubeBase {
+ sk_sp<SkShader> fBmpShader, fImgShader;
+ sk_sp<SkRuntimeEffect> fEffect;
+ SkRRect fRR;
+
+public:
+ SampleBump3D() : SampleCubeBase(kShowLightDome) {}
+
+ SkString name() override { return SkString("bump3d"); }
+
+ void onOnceBeforeDraw() override {
+ fRR = SkRRect::MakeRectXY({20, 20, 380, 380}, 50, 50);
+ auto img = GetResourceAsImage("images/brickwork-texture.jpg");
+ fImgShader = img->makeShader(SkMatrix::MakeScale(2, 2));
+ img = GetResourceAsImage("images/brickwork_normal-map.jpg");
+ fBmpShader = img->makeShader(SkMatrix::MakeScale(2, 2));
+
+ const char code[] = R"(
+ in fragmentProcessor color_map;
+ in fragmentProcessor normal_map;
+
+ uniform float4x4 localToWorld;
+ uniform float4x4 localToWorldAdjInv;
+ uniform float3 lightPos;
+
+ float3 convert_normal_sample(half4 c) {
+ float3 n = 2 * c.rgb - 1;
+ n.y = -n.y;
+ return n;
+ }
+
+ void main(float2 p, inout half4 color) {
+ float3 norm = convert_normal_sample(sample(normal_map, p));
+ float3 plane_norm = normalize(localToWorld * float4(norm, 0)).xyz;
+
+ float3 plane_pos = (localToWorld * float4(p, 0, 1)).xyz;
+ float3 light_dir = normalize(lightPos - plane_pos);
+
+ float ambient = 0.2;
+ float dp = dot(plane_norm, light_dir);
+ float scale = min(ambient + max(dp, 0), 1);
+
+ color = sample(color_map, p) * half4(float4(scale, scale, scale, 1));
+ }
+ )";
+ auto [effect, error] = SkRuntimeEffect::Make(SkString(code));
+ if (!effect) {
+ SkDebugf("runtime error %s\n", error.c_str());
+ }
+ fEffect = effect;
+ }
+
+ void drawContent(SkCanvas* canvas, SkColor color, int index, bool drawFront) override {
+ if (!drawFront || !front(canvas->experimental_getLocalToDevice())) {
+ return;
+ }
+
+ auto adj_inv = [](const SkM44& m) {
+ SkM44 inv;
+ SkAssertResult(m.invert(&inv));
+ return inv.transpose();
+ };
+
+ struct Uniforms {
+ SkM44 fLocalToWorld;
+ SkM44 fLocalToWorldAdjInv;
+ SkV3 fLightPos;
+ } uni;
+ uni.fLocalToWorld = canvas->experimental_getLocalToWorld();
+ uni.fLocalToWorldAdjInv = adj_inv(uni.fLocalToWorld);
+ uni.fLightPos = fLight.computeWorldPos(fSphere);
+
+ sk_sp<SkData> data = SkData::MakeWithCopy(&uni, sizeof(uni));
+ sk_sp<SkShader> children[] = { fImgShader, fBmpShader };
+
+ SkPaint paint;
+ paint.setColor(color);
+ paint.setShader(fEffect->makeShader(data, children, 2, nullptr, true));
+
+ canvas->drawRRect(fRR, paint);
+ }
+};
DEF_SAMPLE( return new SampleBump3D; )
+
+#include "modules/skottie/include/Skottie.h"
+
+class SampleSkottieCube : public SampleCubeBase {
+ sk_sp<skottie::Animation> fAnim[6];
+
+public:
+ SampleSkottieCube() : SampleCubeBase(kCanRunOnCPU) {}
+
+ SkString name() override { return SkString("skottie3d"); }
+
+ void onOnceBeforeDraw() override {
+ const char* files[] = {
+ "skottie/skottie-chained-mattes.json",
+ "skottie/skottie-gradient-ramp.json",
+ "skottie/skottie_sample_2.json",
+ "skottie/skottie-3d-3planes.json",
+ "skottie/skottie-text-animator-4.json",
+ "skottie/skottie-motiontile-effect-phase.json",
+
+ };
+ for (unsigned i = 0; i < SK_ARRAY_COUNT(files); ++i) {
+ if (auto stream = GetResourceAsStream(files[i])) {
+ fAnim[i] = skottie::Animation::Make(stream.get());
+ }
+ }
+ }
+
+ void drawContent(SkCanvas* canvas, SkColor color, int index, bool drawFront) override {
+ if (!drawFront || !front(canvas->experimental_getLocalToDevice())) {
+ return;
+ }
+
+ SkPaint paint;
+ paint.setColor(color);
+ SkRect r = {0, 0, 400, 400};
+ canvas->drawRect(r, paint);
+ fAnim[index]->render(canvas, &r);
+ }
+
+ bool onAnimate(double nanos) override {
+ for (auto& anim : fAnim) {
+ SkScalar dur = anim->duration();
+ SkScalar t = fmod(1e-9 * nanos, dur) / dur;
+ anim->seek(t);
+ }
+ return true;
+ }
+};
+DEF_SAMPLE( return new SampleSkottieCube; )