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