|
|
Apply the given stencil operator for each pixel in the array whose mask flag is set.
- Note:
- This is for software stencil buffers only. Input: n - number of pixels in the span x, y - array of [n] pixels operator - the stencil buffer operator mask - array [n] of flag: 1=apply operator, 0=don't apply operator
Definition at line 532 of file s_stencil.c.
Referenced by stencil_and_ztest_pixels(), and stencil_test_pixels().
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
struct gl_renderbuffer *rb = fb->_StencilBuffer;
const GLstencil stencilMax = (1 << fb->Visual.stencilBits) - 1;
const GLstencil ref = ctx->Stencil.Ref[face];
const GLstencil wrtmask = ctx->Stencil.WriteMask[face];
const GLstencil invmask = (GLstencil) (~wrtmask);
GLuint i;
GLstencil *stencilStart = (GLubyte *) rb->Data;
const GLuint stride = rb->Width;
ASSERT(rb->GetPointer(ctx, rb, 0, 0));
ASSERT(sizeof(GLstencil) == 1);
switch (oper) {
case GL_KEEP:
break;
case GL_ZERO:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = 0;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) (invmask & *sptr);
}
}
}
break;
case GL_REPLACE:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = ref;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) ((invmask & *sptr ) | (wrtmask & ref));
}
}
}
break;
case GL_INCR:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr < stencilMax) {
*sptr = (GLstencil) (*sptr + 1);
}
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr < stencilMax) {
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
}
}
}
}
break;
case GL_DECR:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr>0) {
*sptr = (GLstencil) (*sptr - 1);
}
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr>0) {
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
}
}
}
}
break;
case GL_INCR_WRAP_EXT:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) (*sptr + 1);
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
}
}
}
break;
case GL_DECR_WRAP_EXT:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) (*sptr - 1);
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
}
}
}
break;
case GL_INVERT:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) (~*sptr);
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & ~*sptr));
}
}
}
break;
default:
_mesa_problem(ctx, "Bad stencilop in apply_stencil_op_to_pixels");
}
}
|