|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tstencilcontrol.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tthreadmessage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include <stack></stack>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <qthreadstorage></qthreadstorage>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// singleton
|
|
Shinya Kitaoka |
120a6e |
class StencilControlManager {
|
|
Shinya Kitaoka |
120a6e |
QThreadStorage<tstencilcontrol *=""> m_storage;</tstencilcontrol>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
StencilControlManager() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
static StencilControlManager *instance() {
|
|
Shinya Kitaoka |
120a6e |
static StencilControlManager theInstance;
|
|
Shinya Kitaoka |
120a6e |
return &theInstance;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStencilControl *getCurrentStencilControl() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_storage.hasLocalData()) {
|
|
Shinya Kitaoka |
120a6e |
m_storage.setLocalData(new TStencilControl);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return m_storage.localData();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~StencilControlManager() {}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // Local namepace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TStencilControl::Imp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
int m_stencilBitCount;
|
|
Shinya Kitaoka |
120a6e |
int m_pushCount;
|
|
Shinya Kitaoka |
120a6e |
int m_currentWriting; // current stencil bit plane.
|
|
Shinya Kitaoka |
120a6e |
// 0 is the first bit plane ; -1 menas no stencil mask is writing
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int m_virtualState;
|
|
Shinya Kitaoka |
120a6e |
// the state of the (eventually virtual) top mask.
|
|
Shinya Kitaoka |
120a6e |
// A mask is virtual if overflows stencil buffer
|
|
Shinya Kitaoka |
120a6e |
// 0 is closed and disabled, 1 closed and enabled and 2 is opened
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
std::stack<bool> fullState;</bool>
|
|
Toshihiro Shimizu |
890ddd |
// state of each mask in the stack (except top mask).
|
|
Toshihiro Shimizu |
890ddd |
// 'true' means opend; 'false' means close and enabled
|
|
Toshihiro Shimizu |
890ddd |
// Used only for assert
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
unsigned char m_writingMask; // bit mask. The i-th bit=1 iff the i-th mask is
|
|
Shinya Kitaoka |
120a6e |
// opened to write
|
|
Shinya Kitaoka |
120a6e |
unsigned char m_drawOnScreenMask; // bitmsk.The ith bit=1 iff the ith mask
|
|
Shinya Kitaoka |
120a6e |
// WRITE also ON SCREEN WHEN WRITE ON
|
|
Shinya Kitaoka |
120a6e |
// STENCIL BIT PLANE
|
|
Shinya Kitaoka |
120a6e |
unsigned char
|
|
Shinya Kitaoka |
120a6e |
m_enabledMask; // bit mask. The i-th bit=1 iff the i-th mask is enabled
|
|
Shinya Kitaoka |
120a6e |
unsigned char
|
|
Shinya Kitaoka |
120a6e |
m_inOrOutMask; // bit mask. The i-th bit=1 iff the i-th mask is inside
|
|
Shinya Kitaoka |
120a6e |
unsigned char m_drawOnlyOnceMask;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Imp();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void updateOpenGlState();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void pushMask();
|
|
Shinya Kitaoka |
120a6e |
// make a new stencil plane the current one.
|
|
Shinya Kitaoka |
120a6e |
// if there is no plane available, increase a counter and does not push
|
|
Shinya Kitaoka |
120a6e |
// (virtual masks)
|
|
Shinya Kitaoka |
120a6e |
// So the same number of pop has no effect
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void popMask();
|
|
Shinya Kitaoka |
120a6e |
// assert if the stencil stack contains only 0
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void beginMask(DrawMode drawMode);
|
|
Shinya Kitaoka |
120a6e |
// clear the current stencil plane; start writing to it
|
|
Shinya Kitaoka |
120a6e |
// if drawOnScreen is not 0, it writes also to the color buffer (or stencil
|
|
Shinya Kitaoka |
120a6e |
// plane if another
|
|
Shinya Kitaoka |
120a6e |
// mask is open). If drawOnScreen is 2, it drows only once (by stencil buffer)
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void endMask();
|
|
Shinya Kitaoka |
120a6e |
// end writing to the stencil plane.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void enableMask(MaskType maskType);
|
|
Shinya Kitaoka |
120a6e |
void disableMask();
|
|
Shinya Kitaoka |
120a6e |
// between enableMask()/disableMask() drawing is filtered by the values of the
|
|
Shinya Kitaoka |
120a6e |
// current
|
|
Shinya Kitaoka |
120a6e |
// stencil plane
|
|
Shinya Kitaoka |
120a6e |
// n.b. enableMask()/disableMask() can be nidified. Between the inner pair
|
|
Shinya Kitaoka |
120a6e |
// writing is enabled
|
|
Shinya Kitaoka |
120a6e |
// according to the AND of all of them
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStencilControl::Imp::Imp()
|
|
Shinya Kitaoka |
120a6e |
: m_stencilBitCount(0)
|
|
Shinya Kitaoka |
120a6e |
, m_pushCount(1)
|
|
Shinya Kitaoka |
120a6e |
, m_currentWriting(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_enabledMask(0)
|
|
Shinya Kitaoka |
120a6e |
, m_writingMask(0)
|
|
Shinya Kitaoka |
120a6e |
, m_inOrOutMask(0)
|
|
Shinya Kitaoka |
120a6e |
, m_drawOnScreenMask(0)
|
|
Shinya Kitaoka |
120a6e |
, m_drawOnlyOnceMask(0)
|
|
Shinya Kitaoka |
120a6e |
, m_virtualState(0) {
|
|
Shinya Kitaoka |
120a6e |
glGetIntegerv(GL_STENCIL_BITS, (GLint *)&m_stencilBitCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glStencilMask(0xFFFFFFFF);
|
|
Shinya Kitaoka |
120a6e |
// glClearStencil(0);
|
|
Shinya Kitaoka |
120a6e |
glClear(GL_STENCIL_BUFFER_BIT);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStencilControl *TStencilControl::instance() {
|
|
Shinya Kitaoka |
120a6e |
StencilControlManager *instance = StencilControlManager::instance();
|
|
Shinya Kitaoka |
120a6e |
return instance->getCurrentStencilControl();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::TStencilControl() : m_imp(new Imp) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::~TStencilControl() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::Imp::updateOpenGlState() {
|
|
Shinya Kitaoka |
120a6e |
if (m_currentWriting >= 0) { // writing on stencil buffer
|
|
Shinya Kitaoka |
120a6e |
unsigned char currentWritingMask = 1 << m_currentWriting;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool drawOnlyOnce = (currentWritingMask & m_drawOnlyOnceMask) != 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (currentWritingMask & m_drawOnScreenMask) {
|
|
Shinya Kitaoka |
120a6e |
unsigned char lastWritingMask;
|
|
Shinya Kitaoka |
120a6e |
int lastWriting = m_currentWriting - 1;
|
|
Shinya Kitaoka |
120a6e |
for (; lastWriting >= 0; lastWriting--) {
|
|
Shinya Kitaoka |
120a6e |
lastWritingMask = 1 << lastWriting;
|
|
Shinya Kitaoka |
120a6e |
if ((lastWritingMask & m_writingMask) == lastWritingMask) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (lastWriting < 0) {
|
|
Shinya Kitaoka |
120a6e |
// glColorMask(1,1,1,1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (drawOnlyOnce)
|
|
Shinya Kitaoka |
120a6e |
m_enabledMask |= currentWritingMask;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_enabledMask &= ~currentWritingMask;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
tglMultColorMask(0, 0, 0, 0);
|
|
Shinya Kitaoka |
120a6e |
// glDrawBuffer(GL_NONE);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
drawOnlyOnce = false; // essendo solo un'effetto visivo, se sto
|
|
Shinya Kitaoka |
120a6e |
// scrivendo su una maschera e non a schermo, e'
|
|
Shinya Kitaoka |
120a6e |
// inutile
|
|
Shinya Kitaoka |
120a6e |
currentWritingMask |= lastWritingMask;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
tglMultColorMask(0, 0, 0, 0);
|
|
Shinya Kitaoka |
120a6e |
// glDrawBuffer(GL_NONE);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glStencilMask(currentWritingMask);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (drawOnlyOnce) {
|
|
Shinya Kitaoka |
120a6e |
glStencilFunc(GL_EQUAL, m_inOrOutMask, m_enabledMask);
|
|
Shinya Kitaoka |
120a6e |
glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
glStencilFunc(GL_EQUAL, currentWritingMask | m_inOrOutMask,
|
|
Shinya Kitaoka |
120a6e |
m_enabledMask);
|
|
Shinya Kitaoka |
120a6e |
glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
} else { // writing on screen buffer
|
|
Shinya Kitaoka |
120a6e |
glStencilMask(0xFFFFFFFF);
|
|
Shinya Kitaoka |
120a6e |
glStencilFunc(GL_EQUAL, m_inOrOutMask, m_enabledMask);
|
|
Shinya Kitaoka |
120a6e |
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
|
Shinya Kitaoka |
120a6e |
// glColorMask(1,1,1,1);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_enabledMask && m_currentWriting < 0)
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_STENCIL_TEST);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_STENCIL_TEST);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::Imp::pushMask() { m_pushCount++; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::Imp::beginMask(DrawMode drawMode) {
|
|
Shinya Kitaoka |
120a6e |
m_currentWriting = m_pushCount - 1;
|
|
Shinya Kitaoka |
120a6e |
unsigned char currentMask = 1 << m_currentWriting;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_writingMask |= currentMask;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (drawMode == DRAW_ALSO_ON_SCREEN) {
|
|
Shinya Kitaoka |
120a6e |
m_drawOnScreenMask |= currentMask;
|
|
Shinya Kitaoka |
120a6e |
} else if (drawMode == DRAW_ON_SCREEN_ONLY_ONCE) {
|
|
Shinya Kitaoka |
120a6e |
m_drawOnScreenMask |= currentMask;
|
|
Shinya Kitaoka |
120a6e |
m_drawOnlyOnceMask |= currentMask;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_drawOnScreenMask &= ~currentMask;
|
|
Shinya Kitaoka |
120a6e |
m_drawOnlyOnceMask &= ~currentMask;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_STENCIL_TEST);
|
|
Shinya Kitaoka |
120a6e |
glStencilMask(currentMask); // enabled to modify only current bitPlane
|
|
Shinya Kitaoka |
120a6e |
glClear(GL_STENCIL_BUFFER_BIT); // and clear it
|
|
Shinya Kitaoka |
120a6e |
updateOpenGlState();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::Imp::endMask() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_pushCount - 1 == m_currentWriting);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
unsigned char currentMask = 1 << (m_pushCount - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_writingMask &= ~currentMask; // stop writing
|
|
Shinya Kitaoka |
120a6e |
m_enabledMask &= ~currentMask;
|
|
Shinya Kitaoka |
120a6e |
m_drawOnScreenMask &= ~currentMask;
|
|
Shinya Kitaoka |
120a6e |
m_drawOnlyOnceMask &= ~currentMask;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_currentWriting--;
|
|
Shinya Kitaoka |
120a6e |
for (; m_currentWriting >= 0; m_currentWriting--) {
|
|
Shinya Kitaoka |
120a6e |
unsigned char currentWritingMask = 1 << m_currentWriting;
|
|
Shinya Kitaoka |
120a6e |
if ((currentWritingMask & m_writingMask) == currentWritingMask) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
updateOpenGlState();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::Imp::enableMask(MaskType maskType) {
|
|
Shinya Kitaoka |
120a6e |
unsigned char currentMask = 1 << (m_pushCount - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if ((m_enabledMask & currentMask) == 0) glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_enabledMask |= currentMask;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(maskType == SHOW_INSIDE || maskType == SHOW_OUTSIDE);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (maskType == SHOW_INSIDE)
|
|
Shinya Kitaoka |
120a6e |
m_inOrOutMask |= currentMask;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_inOrOutMask &= ~currentMask;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
updateOpenGlState();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::Imp::disableMask() {
|
|
Shinya Kitaoka |
120a6e |
unsigned char currentMask = 1 << (m_pushCount - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_enabledMask &= ~currentMask;
|
|
Shinya Kitaoka |
120a6e |
m_inOrOutMask &= ~currentMask;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
updateOpenGlState();
|
|
Shinya Kitaoka |
120a6e |
glPopAttrib();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::Imp::popMask() {
|
|
Shinya Kitaoka |
120a6e |
--m_pushCount;
|
|
Shinya Kitaoka |
120a6e |
assert(m_pushCount > 0); // there is at least one mask in the stack
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// questo forse e' un po' brutto:
|
|
Shinya Kitaoka |
120a6e |
// La maschera e' chiusa.
|
|
Shinya Kitaoka |
120a6e |
// Se e' abilitata, open = push+open
|
|
Shinya Kitaoka |
120a6e |
// Se e' disabilitata, open = open
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::beginMask(DrawMode drawMode) {
|
|
Shinya Kitaoka |
120a6e |
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_virtualState) // opened or enabled
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
m_imp->fullState.push(m_imp->m_virtualState == 2);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->pushMask();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_virtualState = 2; // opened
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_pushCount <= m_imp->m_stencilBitCount)
|
|
Shinya Kitaoka |
120a6e |
m_imp->beginMask(drawMode);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::endMask() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_virtualState) // closed and disabled
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
m_imp->popMask();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp->fullState.top()); // the state before last push must be
|
|
Shinya Kitaoka |
120a6e |
// opened
|
|
Shinya Kitaoka |
120a6e |
m_imp->fullState.pop();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp->m_virtualState != 1); // yet closed
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_virtualState = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_pushCount <= m_imp->m_stencilBitCount) m_imp->endMask();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPopAttrib();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::enableMask(MaskType maskType) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp->m_virtualState != 2); // cannot enable an opened mask
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_virtualState = 1; // enabled
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_pushCount <= m_imp->m_stencilBitCount)
|
|
Shinya Kitaoka |
120a6e |
m_imp->enableMask(maskType);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TStencilControl::disableMask() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp->m_virtualState != 2); // cannot disable an opened mask
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_virtualState) // closed and disabled
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
m_imp->popMask();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
assert(
|
|
Shinya Kitaoka |
120a6e |
!m_imp->fullState.top()); // the state before last push must be enabled
|
|
Shinya Kitaoka |
120a6e |
m_imp->fullState.pop();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_virtualState = 0; // close and disabled
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_pushCount <= m_imp->m_stencilBitCount) m_imp->disableMask();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|