From f621472b7c68fe2a95a67aaa1cd619d779733b4d Mon Sep 17 00:00:00 2001 From: David Capello Date: Fri, 16 Sep 2022 15:19:17 -0300 Subject: [PATCH] Draw cels creating a SkShader from SkImage directly from the doc::Image data --- src/app/render/shader_renderer.cpp | 62 ++++++++++++++++++++++++++++++ src/app/render/shader_renderer.h | 7 ++++ 2 files changed, 69 insertions(+) diff --git a/src/app/render/shader_renderer.cpp b/src/app/render/shader_renderer.cpp index e2914ea96..0583b67f5 100644 --- a/src/app/render/shader_renderer.cpp +++ b/src/app/render/shader_renderer.cpp @@ -151,10 +151,72 @@ void ShaderRenderer::renderSprite(os::Surface* dstSurface, p.setShader(builder.makeShader()); canvas->drawRect(SkRect::MakeXYWH(area.dst.x, area.dst.y, area.size.w, area.size.h), p); + + // Draw cels + drawLayerGroup(canvas, sprite, sprite->root(), frame, area); } canvas->restore(); } +void ShaderRenderer::drawLayerGroup(SkCanvas* canvas, + const doc::Sprite* sprite, + const doc::LayerGroup* group, + const doc::frame_t frame, + const gfx::ClipF& area) +{ + for (auto layer : group->layers()) { + switch (layer->type()) { + + case doc::ObjectType::LayerImage: { + auto imageLayer = static_cast(layer); + + if (doc::Cel* cel = imageLayer->cel(frame)) { + doc::Image* image = cel->image(); + + auto skData = SkData::MakeWithoutCopy( + (const void*)image->getPixelAddress(0, 0), + image->getMemSize()); + + // TODO support other color modes + ASSERT(image->colorMode() == doc::ColorMode::RGB); + + auto skImg = SkImage::MakeRasterData( + SkImageInfo::Make(image->width(), + image->height(), + kRGBA_8888_SkColorType, + kUnpremul_SkAlphaType), + skData, + image->getRowStrideSize()); + + sk_sp imgShader = skImg->makeShader(SkSamplingOptions(SkFilterMode::kLinear)); + + SkPaint p; + p.setStyle(SkPaint::kFill_Style); + p.setShader(imgShader); + + canvas->save(); + canvas->translate(SkIntToScalar(area.dst.x + cel->x() - area.src.x), + SkIntToScalar(area.dst.y + cel->y() - area.src.y)); + canvas->drawRect(SkRect::MakeXYWH(0, 0, image->width(), image->height()), p); + canvas->restore(); + } + break; + } + + case doc::ObjectType::LayerTilemap: + // TODO impl + break; + + case doc::ObjectType::LayerGroup: + // TODO draw a group in a sub-surface and then compose that surface + drawLayerGroup(canvas, sprite, + static_cast(layer), + frame, area); + break; + } + } +} + void ShaderRenderer::renderCheckeredBackground(doc::Image* dstImage, const gfx::Clip& area) { diff --git a/src/app/render/shader_renderer.h b/src/app/render/shader_renderer.h index 33aace575..d37fc33f2 100644 --- a/src/app/render/shader_renderer.h +++ b/src/app/render/shader_renderer.h @@ -14,6 +14,7 @@ #include "include/core/SkRefCnt.h" +class SkCanvas; class SkRuntimeEffect; namespace app { @@ -67,6 +68,12 @@ namespace app { const doc::BlendMode blendMode) override; private: + void drawLayerGroup(SkCanvas* canvas, + const doc::Sprite* sprite, + const doc::LayerGroup* group, + const doc::frame_t frame, + const gfx::ClipF& area); + render::BgOptions m_bgOptions; sk_sp m_bgEffect; };