mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
common paint: introduce opacity() method.
We introduced separate opacity interface to adjust alpha value by paint. This opacity will affect to whole paint image if paint is a group of paints. Also, this opacity is to multipy with fill/stroke alpha values. This means if the opacity is valid, the paint might deal with a composition step, which is very expensive due to additional rendering step. One tip is, if you want to toggle on/off for a certian paint, you can set opacity to 255 or 0. @API Additions: Result Paint::opacity(uint8_t o) noexcept; uint8_t Paint::opacity() const noexcept; @Examples: examples/Opacity @Issues: 94
This commit is contained in:
parent
da4b57e763
commit
0399d84478
14 changed files with 223 additions and 21 deletions
|
@ -93,10 +93,13 @@ public:
|
||||||
Result translate(float x, float y) noexcept;
|
Result translate(float x, float y) noexcept;
|
||||||
Result transform(const Matrix& m) noexcept;
|
Result transform(const Matrix& m) noexcept;
|
||||||
Result bounds(float* x, float* y, float* w, float* h) const noexcept;
|
Result bounds(float* x, float* y, float* w, float* h) const noexcept;
|
||||||
|
Result opacity(uint8_t o) noexcept;
|
||||||
Paint* duplicate() const noexcept;
|
Paint* duplicate() const noexcept;
|
||||||
|
|
||||||
Result composite(std::unique_ptr<Paint> target, CompositeMethod method) const noexcept;
|
Result composite(std::unique_ptr<Paint> target, CompositeMethod method) const noexcept;
|
||||||
|
|
||||||
|
uint8_t opacity() const noexcept;
|
||||||
|
|
||||||
_TVG_DECLARE_ACCESSOR();
|
_TVG_DECLARE_ACCESSOR();
|
||||||
_TVG_DECLARE_PRIVATE(Paint);
|
_TVG_DECLARE_PRIVATE(Paint);
|
||||||
};
|
};
|
||||||
|
|
166
src/examples/Opacity.cpp
Normal file
166
src/examples/Opacity.cpp
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* Drawing Commands */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
void tvgDrawCmds(tvg::Canvas* canvas)
|
||||||
|
{
|
||||||
|
if (!canvas) return;
|
||||||
|
|
||||||
|
//Prepare Circle
|
||||||
|
auto shape1 = tvg::Shape::gen();
|
||||||
|
shape1->appendCircle(400, 400, 250, 250);
|
||||||
|
shape1->fill(255, 255, 0, 255);
|
||||||
|
canvas->push(move(shape1));
|
||||||
|
|
||||||
|
//Create a Scene
|
||||||
|
auto scene = tvg::Scene::gen();
|
||||||
|
scene->opacity(127); //Apply opacity to scene (0 - 255)
|
||||||
|
scene->reserve(2);
|
||||||
|
|
||||||
|
//Star
|
||||||
|
auto shape2 = tvg::Shape::gen();
|
||||||
|
|
||||||
|
//Appends Paths
|
||||||
|
shape2->moveTo(199, 34);
|
||||||
|
shape2->lineTo(253, 143);
|
||||||
|
shape2->lineTo(374, 160);
|
||||||
|
shape2->lineTo(287, 244);
|
||||||
|
shape2->lineTo(307, 365);
|
||||||
|
shape2->lineTo(199, 309);
|
||||||
|
shape2->lineTo(97, 365);
|
||||||
|
shape2->lineTo(112, 245);
|
||||||
|
shape2->lineTo(26, 161);
|
||||||
|
shape2->lineTo(146, 143);
|
||||||
|
shape2->close();
|
||||||
|
shape2->fill(0, 0, 255, 255);
|
||||||
|
scene->push(move(shape2));
|
||||||
|
|
||||||
|
//Circle
|
||||||
|
auto shape3 = tvg::Shape::gen();
|
||||||
|
|
||||||
|
auto cx = 550.0f;
|
||||||
|
auto cy = 550.0f;
|
||||||
|
auto radius = 125.0f;
|
||||||
|
auto halfRadius = radius * 0.552284f;
|
||||||
|
|
||||||
|
//Append Paths
|
||||||
|
shape3->moveTo(cx, cy - radius);
|
||||||
|
shape3->cubicTo(cx + halfRadius, cy - radius, cx + radius, cy - halfRadius, cx + radius, cy);
|
||||||
|
shape3->cubicTo(cx + radius, cy + halfRadius, cx + halfRadius, cy + radius, cx, cy+ radius);
|
||||||
|
shape3->cubicTo(cx - halfRadius, cy + radius, cx - radius, cy + halfRadius, cx - radius, cy);
|
||||||
|
shape3->cubicTo(cx - radius, cy - halfRadius, cx - halfRadius, cy - radius, cx, cy - radius);
|
||||||
|
shape3->fill(255, 0, 0, 255);
|
||||||
|
scene->push(move(shape3));
|
||||||
|
|
||||||
|
//Draw the Scene onto the Canvas
|
||||||
|
canvas->push(move(scene));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* Sw Engine Test Code */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
static unique_ptr<tvg::SwCanvas> swCanvas;
|
||||||
|
|
||||||
|
void tvgSwTest(uint32_t* buffer)
|
||||||
|
{
|
||||||
|
//Create a Canvas
|
||||||
|
swCanvas = tvg::SwCanvas::gen();
|
||||||
|
swCanvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
|
||||||
|
|
||||||
|
/* Push the shape into the Canvas drawing list
|
||||||
|
When this shape is into the canvas list, the shape could update & prepare
|
||||||
|
internal data asynchronously for coming rendering.
|
||||||
|
Canvas keeps this shape node unless user call canvas->clear() */
|
||||||
|
tvgDrawCmds(swCanvas.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawSwView(void* data, Eo* obj)
|
||||||
|
{
|
||||||
|
if (swCanvas->draw() == tvg::Result::Success) {
|
||||||
|
swCanvas->sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* GL Engine Test Code */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
static unique_ptr<tvg::GlCanvas> glCanvas;
|
||||||
|
|
||||||
|
void initGLview(Evas_Object *obj)
|
||||||
|
{
|
||||||
|
static constexpr auto BPP = 4;
|
||||||
|
|
||||||
|
//Create a Canvas
|
||||||
|
glCanvas = tvg::GlCanvas::gen();
|
||||||
|
glCanvas->target(nullptr, WIDTH * BPP, WIDTH, HEIGHT);
|
||||||
|
|
||||||
|
/* Push the shape into the Canvas drawing list
|
||||||
|
When this shape is into the canvas list, the shape could update & prepare
|
||||||
|
internal data asynchronously for coming rendering.
|
||||||
|
Canvas keeps this shape node unless user call canvas->clear() */
|
||||||
|
tvgDrawCmds(glCanvas.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawGLview(Evas_Object *obj)
|
||||||
|
{
|
||||||
|
auto gl = elm_glview_gl_api_get(obj);
|
||||||
|
gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
gl->glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
if (glCanvas->draw() == tvg::Result::Success) {
|
||||||
|
glCanvas->sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* Main Code */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
if (!strcmp(argv[1], "gl")) tvgEngine = tvg::CanvasEngine::Gl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Initialize ThorVG Engine
|
||||||
|
if (tvgEngine == tvg::CanvasEngine::Sw) {
|
||||||
|
cout << "tvg engine: software" << endl;
|
||||||
|
} else {
|
||||||
|
cout << "tvg engine: opengl" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Threads Count
|
||||||
|
auto threads = std::thread::hardware_concurrency();
|
||||||
|
|
||||||
|
//Initialize ThorVG Engine
|
||||||
|
if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) {
|
||||||
|
|
||||||
|
|
||||||
|
elm_init(argc, argv);
|
||||||
|
|
||||||
|
if (tvgEngine == tvg::CanvasEngine::Sw) {
|
||||||
|
createSwView();
|
||||||
|
} else {
|
||||||
|
createGlView();
|
||||||
|
}
|
||||||
|
|
||||||
|
elm_run();
|
||||||
|
elm_shutdown();
|
||||||
|
|
||||||
|
//Terminate ThorVG Engine
|
||||||
|
tvg::Initializer::term(tvgEngine);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cout << "engine is not supported" << endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ source_file = [
|
||||||
'LinearGradient.cpp',
|
'LinearGradient.cpp',
|
||||||
'MultiCanvas.cpp',
|
'MultiCanvas.cpp',
|
||||||
'MultiShapes.cpp',
|
'MultiShapes.cpp',
|
||||||
|
'Opacity.cpp',
|
||||||
'PathCopy.cpp',
|
'PathCopy.cpp',
|
||||||
'Path.cpp',
|
'Path.cpp',
|
||||||
'RadialGradient.cpp',
|
'RadialGradient.cpp',
|
||||||
|
|
|
@ -140,7 +140,7 @@ bool GlRenderer::dispose(TVG_UNUSED const Shape& shape, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const RenderTransform* transform, vector<Composite>& compList, RenderUpdateFlag flags)
|
void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags)
|
||||||
{
|
{
|
||||||
//prepare shape data
|
//prepare shape data
|
||||||
GlShape* sdata = static_cast<GlShape*>(data);
|
GlShape* sdata = static_cast<GlShape*>(data);
|
||||||
|
|
|
@ -30,7 +30,7 @@ class GlRenderer : public RenderMethod
|
||||||
public:
|
public:
|
||||||
Surface surface = {nullptr, 0, 0, 0};
|
Surface surface = {nullptr, 0, 0, 0};
|
||||||
|
|
||||||
void* prepare(const Shape& shape, void* data, const RenderTransform* transform, vector<Composite>& compList, RenderUpdateFlag flags) override;
|
void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) override;
|
||||||
bool dispose(const Shape& shape, void *data) override;
|
bool dispose(const Shape& shape, void *data) override;
|
||||||
bool preRender() override;
|
bool preRender() override;
|
||||||
bool render(const Shape& shape, void *data) override;
|
bool render(const Shape& shape, void *data) override;
|
||||||
|
|
|
@ -37,9 +37,12 @@ struct SwTask : Task
|
||||||
SwSurface* surface = nullptr;
|
SwSurface* surface = nullptr;
|
||||||
RenderUpdateFlag flags = RenderUpdateFlag::None;
|
RenderUpdateFlag flags = RenderUpdateFlag::None;
|
||||||
vector<Composite> compList;
|
vector<Composite> compList;
|
||||||
|
uint32_t opacity;
|
||||||
|
|
||||||
void run() override
|
void run() override
|
||||||
{
|
{
|
||||||
|
if (opacity == 0) return; //Invisible
|
||||||
|
|
||||||
//Valid Stroking?
|
//Valid Stroking?
|
||||||
uint8_t strokeAlpha = 0;
|
uint8_t strokeAlpha = 0;
|
||||||
auto strokeWidth = sdata->strokeWidth();
|
auto strokeWidth = sdata->strokeWidth();
|
||||||
|
@ -51,12 +54,13 @@ struct SwTask : Task
|
||||||
|
|
||||||
//Invisiable shape turned to visible by alpha.
|
//Invisiable shape turned to visible by alpha.
|
||||||
auto prepareShape = false;
|
auto prepareShape = false;
|
||||||
if (!shapePrepared(&shape) && (flags & RenderUpdateFlag::Color)) prepareShape = true;
|
if (!shapePrepared(&shape) && ((flags & RenderUpdateFlag::Color) || (opacity > 0))) prepareShape = true;
|
||||||
|
|
||||||
//Shape
|
//Shape
|
||||||
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) {
|
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) {
|
||||||
uint8_t alpha = 0;
|
uint8_t alpha = 0;
|
||||||
sdata->fillColor(nullptr, nullptr, nullptr, &alpha);
|
sdata->fillColor(nullptr, nullptr, nullptr, &alpha);
|
||||||
|
alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255);
|
||||||
bool renderShape = (alpha > 0 || sdata->fill());
|
bool renderShape = (alpha > 0 || sdata->fill());
|
||||||
if (renderShape || strokeAlpha) {
|
if (renderShape || strokeAlpha) {
|
||||||
shapeReset(&shape);
|
shapeReset(&shape);
|
||||||
|
@ -181,12 +185,15 @@ bool SwRenderer::render(const Shape& shape, void *data)
|
||||||
|
|
||||||
uint8_t r, g, b, a;
|
uint8_t r, g, b, a;
|
||||||
if (auto fill = task->sdata->fill()) {
|
if (auto fill = task->sdata->fill()) {
|
||||||
|
//FIXME: pass opacity to apply gradient fill?
|
||||||
rasterGradientShape(surface, &task->shape, fill->id());
|
rasterGradientShape(surface, &task->shape, fill->id());
|
||||||
} else{
|
} else{
|
||||||
task->sdata->fillColor(&r, &g, &b, &a);
|
task->sdata->fillColor(&r, &g, &b, &a);
|
||||||
|
a = static_cast<uint8_t>((task->opacity * (uint32_t) a) / 255);
|
||||||
if (a > 0) rasterSolidShape(surface, &task->shape, r, g, b, a);
|
if (a > 0) rasterSolidShape(surface, &task->shape, r, g, b, a);
|
||||||
}
|
}
|
||||||
task->sdata->strokeColor(&r, &g, &b, &a);
|
task->sdata->strokeColor(&r, &g, &b, &a);
|
||||||
|
a = static_cast<uint8_t>((task->opacity * (uint32_t) a) / 255);
|
||||||
if (a > 0) rasterStroke(surface, &task->shape, r, g, b, a);
|
if (a > 0) rasterStroke(surface, &task->shape, r, g, b, a);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -207,7 +214,7 @@ bool SwRenderer::dispose(TVG_UNUSED const Shape& sdata, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, vector<Composite>& compList, RenderUpdateFlag flags)
|
void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags)
|
||||||
{
|
{
|
||||||
//prepare task
|
//prepare task
|
||||||
auto task = static_cast<SwTask*>(data);
|
auto task = static_cast<SwTask*>(data);
|
||||||
|
@ -237,6 +244,7 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform*
|
||||||
task->transform = nullptr;
|
task->transform = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task->opacity = opacity;
|
||||||
task->surface = surface;
|
task->surface = surface;
|
||||||
task->flags = flags;
|
task->flags = flags;
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace tvg
|
||||||
class SwRenderer : public RenderMethod
|
class SwRenderer : public RenderMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void* prepare(const Shape& shape, void* data, const RenderTransform* transform, vector<Composite>& compList, RenderUpdateFlag flags) override;
|
void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) override;
|
||||||
bool dispose(const Shape& shape, void *data) override;
|
bool dispose(const Shape& shape, void *data) override;
|
||||||
bool preRender() override;
|
bool preRender() override;
|
||||||
bool postRender() override;
|
bool postRender() override;
|
||||||
|
|
|
@ -81,11 +81,11 @@ struct Canvas::Impl
|
||||||
|
|
||||||
//Update single paint node
|
//Update single paint node
|
||||||
if (paint) {
|
if (paint) {
|
||||||
paint->pImpl->update(*renderer, nullptr, compList, RenderUpdateFlag::None);
|
paint->pImpl->update(*renderer, nullptr, 255, compList, RenderUpdateFlag::None);
|
||||||
//Update all retained paint nodes
|
//Update all retained paint nodes
|
||||||
} else {
|
} else {
|
||||||
for (auto paint: paints) {
|
for (auto paint: paints) {
|
||||||
paint->pImpl->update(*renderer, nullptr, compList, RenderUpdateFlag::None);
|
paint->pImpl->update(*renderer, nullptr, 255, compList, RenderUpdateFlag::None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
|
|
|
@ -67,20 +67,39 @@ Result Paint::transform(const Matrix& m) noexcept
|
||||||
return Result::FailedAllocation;
|
return Result::FailedAllocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept
|
Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept
|
||||||
{
|
{
|
||||||
if (pImpl->bounds(x, y, w, h)) return Result::Success;
|
if (pImpl->bounds(x, y, w, h)) return Result::Success;
|
||||||
return Result::InsufficientCondition;
|
return Result::InsufficientCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Paint* Paint::duplicate() const noexcept
|
Paint* Paint::duplicate() const noexcept
|
||||||
{
|
{
|
||||||
return pImpl->duplicate();
|
return pImpl->duplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result Paint::composite(std::unique_ptr<Paint> target, CompositeMethod method) const noexcept
|
Result Paint::composite(std::unique_ptr<Paint> target, CompositeMethod method) const noexcept
|
||||||
{
|
{
|
||||||
if (pImpl->composite(target.release(), method)) return Result::Success;
|
if (pImpl->composite(target.release(), method)) return Result::Success;
|
||||||
return Result::InsufficientCondition;
|
return Result::InsufficientCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result Paint::opacity(uint8_t o) noexcept
|
||||||
|
{
|
||||||
|
if (pImpl->opacity == o) return Result::Success;
|
||||||
|
|
||||||
|
pImpl->opacity = o;
|
||||||
|
pImpl->flag |= RenderUpdateFlag::Color;
|
||||||
|
|
||||||
|
return Result::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t Paint::opacity() const noexcept
|
||||||
|
{
|
||||||
|
return pImpl->opacity;
|
||||||
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace tvg
|
||||||
virtual ~StrategyMethod(){}
|
virtual ~StrategyMethod(){}
|
||||||
|
|
||||||
virtual bool dispose(RenderMethod& renderer) = 0;
|
virtual bool dispose(RenderMethod& renderer) = 0;
|
||||||
virtual void* update(RenderMethod& renderer, const RenderTransform* transform, vector<Composite> compList, RenderUpdateFlag pFlag) = 0; //Return engine data if it has.
|
virtual void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite> compList, RenderUpdateFlag pFlag) = 0; //Return engine data if it has.
|
||||||
virtual bool render(RenderMethod& renderer) = 0;
|
virtual bool render(RenderMethod& renderer) = 0;
|
||||||
virtual bool bounds(float* x, float* y, float* w, float* h) const = 0;
|
virtual bool bounds(float* x, float* y, float* w, float* h) const = 0;
|
||||||
virtual Paint* duplicate() = 0;
|
virtual Paint* duplicate() = 0;
|
||||||
|
@ -48,6 +48,8 @@ namespace tvg
|
||||||
Paint* compTarget = nullptr;
|
Paint* compTarget = nullptr;
|
||||||
CompositeMethod compMethod = CompositeMethod::None;
|
CompositeMethod compMethod = CompositeMethod::None;
|
||||||
|
|
||||||
|
uint8_t opacity = 255;
|
||||||
|
|
||||||
~Impl() {
|
~Impl() {
|
||||||
if (smethod) delete(smethod);
|
if (smethod) delete(smethod);
|
||||||
if (rTransform) delete(rTransform);
|
if (rTransform) delete(rTransform);
|
||||||
|
@ -127,7 +129,7 @@ namespace tvg
|
||||||
return smethod->dispose(renderer);
|
return smethod->dispose(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* update(RenderMethod& renderer, const RenderTransform* pTransform, vector<Composite>& compList, uint32_t pFlag)
|
void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, vector<Composite>& compList, uint32_t pFlag)
|
||||||
{
|
{
|
||||||
if (flag & RenderUpdateFlag::Transform) {
|
if (flag & RenderUpdateFlag::Transform) {
|
||||||
if (!rTransform) return nullptr;
|
if (!rTransform) return nullptr;
|
||||||
|
@ -140,20 +142,21 @@ namespace tvg
|
||||||
void *compdata = nullptr;
|
void *compdata = nullptr;
|
||||||
|
|
||||||
if (compTarget && compMethod == CompositeMethod::ClipPath) {
|
if (compTarget && compMethod == CompositeMethod::ClipPath) {
|
||||||
compdata = compTarget->pImpl->update(renderer, pTransform, compList, pFlag);
|
compdata = compTarget->pImpl->update(renderer, pTransform, opacity, compList, pFlag);
|
||||||
if (compdata) compList.push_back({compdata, compMethod});
|
if (compdata) compList.push_back({compdata, compMethod});
|
||||||
}
|
}
|
||||||
|
|
||||||
void *edata = nullptr;
|
void *edata = nullptr;
|
||||||
auto newFlag = static_cast<RenderUpdateFlag>(pFlag | flag);
|
auto newFlag = static_cast<RenderUpdateFlag>(pFlag | flag);
|
||||||
flag = RenderUpdateFlag::None;
|
flag = RenderUpdateFlag::None;
|
||||||
|
opacity = (opacity * this->opacity) / 255;
|
||||||
|
|
||||||
if (rTransform && pTransform) {
|
if (rTransform && pTransform) {
|
||||||
RenderTransform outTransform(pTransform, rTransform);
|
RenderTransform outTransform(pTransform, rTransform);
|
||||||
edata = smethod->update(renderer, &outTransform, compList, newFlag);
|
edata = smethod->update(renderer, &outTransform, opacity, compList, newFlag);
|
||||||
} else {
|
} else {
|
||||||
auto outTransform = pTransform ? pTransform : rTransform;
|
auto outTransform = pTransform ? pTransform : rTransform;
|
||||||
edata = smethod->update(renderer, outTransform, compList, newFlag);
|
edata = smethod->update(renderer, outTransform, opacity, compList, newFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compdata) compList.pop_back();
|
if (compdata) compList.pop_back();
|
||||||
|
@ -179,6 +182,8 @@ namespace tvg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret->pImpl->opacity = opacity;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,9 +215,9 @@ namespace tvg
|
||||||
return inst->dispose(renderer);
|
return inst->dispose(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* update(RenderMethod& renderer, const RenderTransform* transform, vector<Composite> compList, RenderUpdateFlag flag) override
|
void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite> compList, RenderUpdateFlag flag) override
|
||||||
{
|
{
|
||||||
return inst->update(renderer, transform, compList, flag);
|
return inst->update(renderer, transform, opacity, compList, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool render(RenderMethod& renderer) override
|
bool render(RenderMethod& renderer) override
|
||||||
|
|
|
@ -58,13 +58,13 @@ struct Picture::Impl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* update(RenderMethod &renderer, const RenderTransform* transform, vector<Composite>& compList, RenderUpdateFlag flag)
|
void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flag)
|
||||||
{
|
{
|
||||||
reload();
|
reload();
|
||||||
|
|
||||||
if (!paint) return nullptr;
|
if (!paint) return nullptr;
|
||||||
|
|
||||||
return paint->pImpl->update(renderer, transform, compList, flag);
|
return paint->pImpl->update(renderer, transform, opacity, compList, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool render(RenderMethod &renderer)
|
bool render(RenderMethod &renderer)
|
||||||
|
|
|
@ -65,7 +65,7 @@ class RenderMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~RenderMethod() {}
|
virtual ~RenderMethod() {}
|
||||||
virtual void* prepare(TVG_UNUSED const Shape& shape, TVG_UNUSED void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED vector<Composite>& compList, TVG_UNUSED RenderUpdateFlag flags) { return nullptr; }
|
virtual void* prepare(TVG_UNUSED const Shape& shape, TVG_UNUSED void* data, TVG_UNUSED const RenderTransform* transform, uint32_t opacity, TVG_UNUSED vector<Composite>& compList, TVG_UNUSED RenderUpdateFlag flags) { return nullptr; }
|
||||||
virtual bool dispose(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; }
|
virtual bool dispose(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; }
|
||||||
virtual bool preRender() { return true; }
|
virtual bool preRender() { return true; }
|
||||||
virtual bool render(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; }
|
virtual bool render(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; }
|
||||||
|
|
|
@ -44,14 +44,14 @@ struct Scene::Impl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* update(RenderMethod &renderer, const RenderTransform* transform, vector<Composite>& compList, RenderUpdateFlag flag)
|
void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flag)
|
||||||
{
|
{
|
||||||
/* FXIME: it requires to return list of childr engine data
|
/* FXIME: it requires to return list of childr engine data
|
||||||
This is necessary for scene composition */
|
This is necessary for scene composition */
|
||||||
void* edata = nullptr;
|
void* edata = nullptr;
|
||||||
|
|
||||||
for (auto paint: paints) {
|
for (auto paint: paints) {
|
||||||
edata = paint->pImpl->update(renderer, transform, compList, static_cast<uint32_t>(flag));
|
edata = paint->pImpl->update(renderer, transform, opacity, compList, static_cast<uint32_t>(flag));
|
||||||
}
|
}
|
||||||
return edata;
|
return edata;
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,9 +222,9 @@ struct Shape::Impl
|
||||||
return renderer.render(*shape, edata);
|
return renderer.render(*shape, edata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* update(RenderMethod& renderer, const RenderTransform* transform, vector<Composite>& compList, RenderUpdateFlag pFlag)
|
void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag pFlag)
|
||||||
{
|
{
|
||||||
this->edata = renderer.prepare(*shape, this->edata, transform, compList, static_cast<RenderUpdateFlag>(pFlag | flag));
|
this->edata = renderer.prepare(*shape, this->edata, transform, opacity, compList, static_cast<RenderUpdateFlag>(pFlag | flag));
|
||||||
flag = RenderUpdateFlag::None;
|
flag = RenderUpdateFlag::None;
|
||||||
return this->edata;
|
return this->edata;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue