diff --git a/toonz/sources/common/tgl/tstencilcontrol.cpp b/toonz/sources/common/tgl/tstencilcontrol.cpp index 784f6d1d..16870f0f 100644 --- a/toonz/sources/common/tgl/tstencilcontrol.cpp +++ b/toonz/sources/common/tgl/tstencilcontrol.cpp @@ -70,6 +70,9 @@ public: Imp(); + void copy(Imp *src); + void resetMask(); + void updateOpenGlState(); void pushMask(); @@ -121,6 +124,34 @@ TStencilControl::Imp::Imp() //--------------------------------------------------------- +void TStencilControl::Imp::copy(Imp *src) { + m_stencilBitCount = src->m_stencilBitCount; + m_pushCount = src->m_pushCount; + m_currentWriting = src->m_currentWriting; + m_enabledMask = src->m_enabledMask; + m_writingMask = src->m_writingMask; + m_inOrOutMask = src->m_inOrOutMask; + m_drawOnScreenMask = src->m_drawOnScreenMask; + m_drawOnlyOnceMask = src->m_drawOnlyOnceMask; + m_virtualState = src->m_virtualState; +} + +//--------------------------------------------------------- + +void TStencilControl::Imp::resetMask() { + m_stencilBitCount = 0; + m_pushCount = 1; + m_currentWriting = -1; + m_enabledMask = 0; + m_writingMask = 0; + m_inOrOutMask = 0; + m_drawOnScreenMask = 0; + m_drawOnlyOnceMask = 0; + m_virtualState = 0; +} + +//--------------------------------------------------------- + TStencilControl *TStencilControl::instance() { StencilControlManager *instance = StencilControlManager::instance(); return instance->getCurrentStencilControl(); @@ -128,7 +159,7 @@ TStencilControl *TStencilControl::instance() { //--------------------------------------------------------- -TStencilControl::TStencilControl() : m_imp(new Imp) {} +TStencilControl::TStencilControl() : m_imp(new Imp) { m_impStack.empty(); } //--------------------------------------------------------- @@ -364,3 +395,36 @@ void TStencilControl::disableMask() { } //--------------------------------------------------------- + +bool TStencilControl::isMaskEnabled() { return m_imp->m_virtualState > 0; } + +//--------------------------------------------------------- + +void TStencilControl::stashMask() { + Imp *currentImp = new Imp; + currentImp->copy(m_imp.get()); + m_impStack.push(currentImp); + + if (m_imp->m_virtualState == 2) + endMask(); + else if (m_imp->m_virtualState == 1) { + int masks = m_imp->m_pushCount; + for (int i = 0; i < masks; i++) disableMask(); + } +} + +//--------------------------------------------------------- + +void TStencilControl::restoreMask() { + if (m_impStack.top()->m_virtualState == 2) + beginMask(); + else if (m_impStack.top()->m_virtualState == 1) { + int masks = m_impStack.top()->m_pushCount; + for (int i = 0; i < masks; i++) beginMask(); + enableMask(SHOW_INSIDE); + } + + m_imp->copy(m_impStack.top()); + + m_impStack.pop(); +} diff --git a/toonz/sources/include/tstencilcontrol.h b/toonz/sources/include/tstencilcontrol.h index faf43fb7..78b55c8e 100644 --- a/toonz/sources/include/tstencilcontrol.h +++ b/toonz/sources/include/tstencilcontrol.h @@ -4,6 +4,7 @@ #define TSTENCILCONTROL_H #include +#include #include "tcommon.h" @@ -34,6 +35,8 @@ private: class Imp; std::unique_ptr m_imp; + std::stack m_impStack; + public: static TStencilControl *instance(); @@ -45,6 +48,11 @@ public: void enableMask(MaskType maskType); void disableMask(); + + bool isMaskEnabled(); + + void stashMask(); + void restoreMask(); }; //------------------------------------------------------ diff --git a/toonz/sources/toonzlib/textureutils.cpp b/toonz/sources/toonzlib/textureutils.cpp index 98f3466f..5d807159 100644 --- a/toonz/sources/toonzlib/textureutils.cpp +++ b/toonz/sources/toonzlib/textureutils.cpp @@ -14,6 +14,7 @@ #include "toonz/toonzscene.h" #include "toonz/imagemanager.h" #include "imagebuilders.h" +#include "tstencilcontrol.h" // TnzCore includes #include "tpalette.h" @@ -199,7 +200,11 @@ DrawableTextureDataP texture_utils::getTextureData(const TXsheet *xsh, TGlContext currentContext = tglGetCurrentContext(); { tglDoneCurrent(currentContext); + bool masked = TStencilControl::instance()->isMaskEnabled(); + // Must move masks aside when building texture + if (masked) TStencilControl::instance()->stashMask(); xsh->getScene()->renderFrame(tex, frame, xsh, bbox, TAffine()); + if (masked) TStencilControl::instance()->restoreMask(); tglMakeCurrent(currentContext); } #endif