state_stencil.c revision 79664e45c3d7123821dcd5de01991c6de96b8794
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include <stdio.h>
#include "state.h"
#include "state/cr_statetypes.h"
#include "state_internals.h"
static GLint crStateStencilBufferGetIdxAndCount(CRStencilState *s, GLenum face, GLint *pIdx, GLint *pBitsIdx)
{
switch (face)
{
case GL_FRONT_AND_BACK:
*pIdx = 0;
return 2;
case GL_FRONT:
return 1;
case GL_BACK:
return 1;
case 0:
{
/* both front and back */
*pIdx = 0;
return 2;
}
return 1;
default:
return 0;
}
crError("should never be here!");
return 0;
}
{
s->mask = 0xFFFFFFFF;
s->ref = 0;
s->passDepthFail = GL_KEEP;
s->passDepthPass = GL_KEEP;
}
{
}
{
int i;
s->stencilTest = GL_FALSE;
s->stencilTwoSideEXT = GL_FALSE;
s->activeStencilFace = GL_FRONT;
s->clearValue = 0;
s->writeMask = 0xFFFFFFFF;
for (i = 0; i < CRSTATE_STENCIL_BUFFER_COUNT; ++i)
{
crStateStencilBufferInit(&s->buffers[i]);
}
for (i = 0; i < CRSTATE_STENCIL_BUFFER_REF_COUNT; ++i)
{
}
}
static void crStateStencilBufferFunc(CRContext *g, CRStencilBufferState *s, GLenum func, GLint ref, GLuint mask)
{
}
{
CRContext *g = GetCurrentContext();
CRStencilState *s = &(g->stencil);
if (g->current.inBeginEnd)
{
return;
}
FLUSH();
func != GL_GREATER &&
func != GL_NOTEQUAL &&
{
"glStencilFunc called with bogu func: %d", func);
return;
}
if (count)
{
{
}
}
}
{
if (!face)
{
/* crStateStencilFuncPerform accepts 0 value, while glStencilFuncSeparate does not,
* filter it out here */
return;
}
}
{
}
static void STATE_APIENTRY crStateStencilBufferOp (CRContext *g, CRStencilBufferState *s, GLenum fail, GLenum zfail, GLenum zpass)
{
s->passDepthFail = zfail;
s->passDepthPass = zpass;
}
{
CRContext *g = GetCurrentContext();
CRStencilState *s = &(g->stencil);
if (g->current.inBeginEnd)
{
return;
}
FLUSH();
switch (fail) {
case GL_KEEP:
case GL_ZERO:
case GL_REPLACE:
case GL_INCR:
case GL_DECR:
case GL_INVERT:
#ifdef CR_EXT_stencil_wrap
case GL_INCR_WRAP_EXT:
case GL_DECR_WRAP_EXT:
#endif
break;
default:
"glStencilOp called with bogus fail: %d", fail);
return;
}
switch (zfail) {
case GL_KEEP:
case GL_ZERO:
case GL_REPLACE:
case GL_INCR:
case GL_DECR:
case GL_INVERT:
#ifdef CR_EXT_stencil_wrap
case GL_INCR_WRAP_EXT:
case GL_DECR_WRAP_EXT:
#endif
break;
default:
"glStencilOp called with bogus zfail: %d", zfail);
return;
}
switch (zpass) {
case GL_KEEP:
case GL_ZERO:
case GL_REPLACE:
case GL_INCR:
case GL_DECR:
case GL_INVERT:
#ifdef CR_EXT_stencil_wrap
case GL_INCR_WRAP_EXT:
case GL_DECR_WRAP_EXT:
#endif
break;
default:
"glStencilOp called with bogus zpass: %d", zpass);
return;
}
if (count)
{
{
}
}
}
{
if (!face)
{
/* crStateStencilOpPerform accepts 0 value, while glStencilOpSeparate does not,
* filter it out here */
return;
}
}
{
}
{
CRContext *g = GetCurrentContext();
CRStencilState *s = &(g->stencil);
if (g->current.inBeginEnd)
{
return;
}
FLUSH();
s->clearValue = c;
}
{
CRContext *g = GetCurrentContext();
CRStencilState *s = &(g->stencil);
if (g->current.inBeginEnd)
{
return;
}
FLUSH();
}
{
CRContext *g = GetCurrentContext();
CRStencilState *s = &(g->stencil);
switch (face)
{
case GL_FRONT:
case GL_BACK:
s->activeStencilFace = face;
break;
default:
return;
}
}
} while (0)
} while (0)
{
unsigned int j, i;
for (j=0;j<CR_MAX_BITARRAY;j++)
i = 0; /* silence compiler */
{
{
}
}
{
{
}
}
{
{
}
}
/* func */
frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, bitID);
#define CR_STATE_STENCIL_FUNC_FRONT_MATCH() ( \
frontMatch >= 0 ? \
: (frontMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
#define CR_STATE_STENCIL_FUNC_BACK_MATCH() ( \
backMatch >= 0 ? \
: (backMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
#define CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH() ( \
toFrontBackMatch >= 0 ? \
: (toFrontBackMatch = CR_STATE_STENCIL_FUNC_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
if (frontBackDirty)
{
{
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
}
}
}
if (frontDirty)
{
{
{
if (!frontIsSet || !backIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
}
else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
{
if (!frontIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
}
else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
{
if (!backIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
}
}
}
}
if (backDirty)
{
{
{
if (!frontIsSet || !backIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
}
else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
{
if (!frontIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
}
else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
{
if (!backIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK);
}
}
}
}
{
if (CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK))
{
if (activeFace == GL_FRONT)
{
}
CR_STATE_STENCIL_FUNC_COPY(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK);
}
}
/* op */
#define CR_STATE_STENCIL_OP_FRONT_MATCH() ( \
frontMatch >= 0 ? \
: (frontMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
#define CR_STATE_STENCIL_OP_BACK_MATCH() ( \
backMatch >= 0 ? \
: (backMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
#define CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH() ( \
toFrontBackMatch >= 0 ? \
: (toFrontBackMatch = CR_STATE_STENCIL_OP_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
if (frontBackDirty)
{
{
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
{
if (activeFace == GL_BACK)
{
}
}
}
}
if (frontDirty)
{
if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
{
{
if (!frontIsSet || !backIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
}
else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
{
if (!frontIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
}
else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
{
if (!backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
}
}
if (backDirty)
{
if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
{
{
if (!frontIsSet || !backIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
}
else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
{
if (!frontIsSet)
{
if (activeFace == GL_BACK)
{
}
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT);
}
}
else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
{
if (!backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
}
}
{
if (CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK))
{
if (activeFace == GL_FRONT)
{
}
CR_STATE_STENCIL_OP_COPY(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK);
}
}
{
}
{
{
/* we already did it ( see above )*/
/* diff_api.ActiveStencilFaceEXT(to->activeStencilFace); */
}
}
{
{
}
}
}
{
unsigned int j, i;
for (j=0;j<CR_MAX_BITARRAY;j++)
i = 0; /* silence compiler */
{
{
}
}
{
{
}
}
{
{
FILLDIRTY(b->clearValue);
}
}
/* func */
frontBackDirty = CHECKDIRTY(b->bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, bitID);
#define CR_STATE_STENCIL_FUNC_FRONT_MATCH() ( \
frontMatch >= 0 ? \
: (frontMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
#define CR_STATE_STENCIL_FUNC_BACK_MATCH() ( \
backMatch >= 0 ? \
: (backMatch = CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
#define CR_STATE_STENCIL_FUNC_TO_FRONT_BACK_MATCH() ( \
toFrontBackMatch >= 0 ? \
: (toFrontBackMatch = CR_STATE_STENCIL_FUNC_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
if (frontBackDirty)
{
{
{
if (activeFace == GL_BACK)
{
}
}
else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
{
if (activeFace == GL_BACK)
{
}
}
else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
{
if (activeFace == GL_BACK)
{
}
}
}
}
if (frontDirty)
{
{
{
if (!frontIsSet || !backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
{
if (!frontIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
{
if (!backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
}
}
if (backDirty)
{
if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
{
{
if (!frontIsSet || !backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
else if (!CR_STATE_STENCIL_FUNC_FRONT_MATCH())
{
if (!frontIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
else if (!CR_STATE_STENCIL_FUNC_BACK_MATCH())
{
if (!backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
}
}
{
if (CR_STATE_STENCIL_FUNC_MATCH(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK))
{
if (activeFace == GL_FRONT)
{
}
}
}
/* op */
#define CR_STATE_STENCIL_OP_FRONT_MATCH() ( \
frontMatch >= 0 ? \
: (frontMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_FRONT)))
#define CR_STATE_STENCIL_OP_BACK_MATCH() ( \
backMatch >= 0 ? \
: (backMatch = CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_ID_BACK, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
#define CR_STATE_STENCIL_OP_TO_FRONT_BACK_MATCH() ( \
toFrontBackMatch >= 0 ? \
: (toFrontBackMatch = CR_STATE_STENCIL_OP_MATCH(to, CRSTATE_STENCIL_BUFFER_ID_FRONT, to, CRSTATE_STENCIL_BUFFER_ID_BACK)))
if (frontBackDirty)
{
{
{
if (activeFace == GL_BACK)
{
}
}
else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
{
if (activeFace == GL_BACK)
{
}
}
else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
{
if (activeFace == GL_BACK)
{
}
}
}
}
if (frontDirty)
{
if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
{
{
if (!frontIsSet || !backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
{
if (!frontIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
{
if (!backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
}
}
if (backDirty)
{
if (!CR_STATE_STENCIL_OP_BACK_MATCH())
{
{
if (!frontIsSet || !backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
else if (!CR_STATE_STENCIL_OP_FRONT_MATCH())
{
if (!frontIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
else if (!CR_STATE_STENCIL_OP_BACK_MATCH())
{
if (!backIsSet)
{
if (activeFace == GL_BACK)
{
}
}
}
}
}
{
if (CR_STATE_STENCIL_OP_MATCH(from, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK, to, CRSTATE_STENCIL_BUFFER_REF_ID_TWO_SIDE_BACK))
{
if (activeFace == GL_FRONT)
{
}
}
}
{
}
{
{
/* we already did it ( see above )*/
/* diff_api.ActiveStencilFaceEXT(to->activeStencilFace); */
}
}
{
{
}
}
}