ReactOS 0.4.15-dev-8116-gf69e256
stencil.c File Reference
#include <stdlib.h>
#include <string.h>
#include "context.h"
#include "dlist.h"
#include "macros.h"
#include "pb.h"
#include "stencil.h"
#include "types.h"
Include dependency graph for stencil.c:

Go to the source code of this file.

Macros

#define STENCIL_ADDRESS(X, Y)   (ctx->Buffer->Stencil + ctx->Buffer->Width * (Y) + (X))
 

Functions

void gl_ClearStencil (GLcontext *ctx, GLint s)
 
void gl_StencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask)
 
void gl_StencilMask (GLcontext *ctx, GLuint mask)
 
void gl_StencilOp (GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass)
 
static void apply_stencil_op_to_span (GLcontext *ctx, GLuint n, GLint x, GLint y, GLenum oper, GLubyte mask[])
 
GLint gl_stencil_span (GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte mask[])
 
void gl_depth_stencil_span (GLcontext *ctx, GLuint n, GLint x, GLint y, const GLdepth z[], GLubyte mask[])
 
static void apply_stencil_op_to_pixels (GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLenum oper, GLubyte mask[])
 
GLint gl_stencil_pixels (GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLubyte mask[])
 
void gl_depth_stencil_pixels (GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], const GLdepth z[], GLubyte mask[])
 
void gl_read_stencil_span (GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte stencil[])
 
void gl_write_stencil_span (GLcontext *ctx, GLuint n, GLint x, GLint y, const GLubyte stencil[])
 
void gl_alloc_stencil_buffer (GLcontext *ctx)
 
void gl_clear_stencil_buffer (GLcontext *ctx)
 

Macro Definition Documentation

◆ STENCIL_ADDRESS

#define STENCIL_ADDRESS (   X,
  Y 
)    (ctx->Buffer->Stencil + ctx->Buffer->Width * (Y) + (X))

Definition at line 70 of file stencil.c.

Function Documentation

◆ apply_stencil_op_to_pixels()

static void apply_stencil_op_to_pixels ( GLcontext ctx,
GLuint  n,
const GLint  x[],
const GLint  y[],
GLenum  oper,
GLubyte  mask[] 
)
static

Definition at line 570 of file stencil.c.

574{
575 GLint i;
577 GLstencil wrtmask, invmask;
578
579 wrtmask = ctx->Stencil.WriteMask;
580 invmask = ~ctx->Stencil.WriteMask;
581
582 ref = ctx->Stencil.Ref;
583
584 switch (oper) {
585 case GL_KEEP:
586 /* do nothing */
587 break;
588 case GL_ZERO:
589 if (invmask==0) {
590 for (i=0;i<n;i++) {
591 if (mask[i]) {
592 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
593 *sptr = 0;
594 }
595 }
596 }
597 else {
598 for (i=0;i<n;i++) {
599 if (mask[i]) {
600 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
601 *sptr = invmask & *sptr;
602 }
603 }
604 }
605 break;
606 case GL_REPLACE:
607 if (invmask==0) {
608 for (i=0;i<n;i++) {
609 if (mask[i]) {
610 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
611 *sptr = ref;
612 }
613 }
614 }
615 else {
616 for (i=0;i<n;i++) {
617 if (mask[i]) {
618 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
619 *sptr = (invmask & *sptr ) | (wrtmask & ref);
620 }
621 }
622 }
623 break;
624 case GL_INCR:
625 if (invmask==0) {
626 for (i=0;i<n;i++) {
627 if (mask[i]) {
628 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
629 if (*sptr < 0xff) {
630 *sptr = *sptr + 1;
631 }
632 }
633 }
634 }
635 else {
636 for (i=0;i<n;i++) {
637 if (mask[i]) {
638 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
639 if (*sptr<0xff) {
640 *sptr = (invmask & *sptr) | (wrtmask & (*sptr+1));
641 }
642 }
643 }
644 }
645 break;
646 case GL_DECR:
647 if (invmask==0) {
648 for (i=0;i<n;i++) {
649 if (mask[i]) {
650 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
651 if (*sptr>0) {
652 *sptr = *sptr - 1;
653 }
654 }
655 }
656 }
657 else {
658 for (i=0;i<n;i++) {
659 if (mask[i]) {
660 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
661 if (*sptr>0) {
662 *sptr = (invmask & *sptr) | (wrtmask & (*sptr-1));
663 }
664 }
665 }
666 }
667 break;
668 case GL_INVERT:
669 if (invmask==0) {
670 for (i=0;i<n;i++) {
671 if (mask[i]) {
672 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
673 *sptr = ~*sptr;
674 }
675 }
676 }
677 else {
678 for (i=0;i<n;i++) {
679 if (mask[i]) {
680 GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
681 *sptr = (invmask & *sptr) | (wrtmask & ~*sptr);
682 }
683 }
684 }
685 break;
686 default:
687 gl_problem(ctx, "Bad stencilop in apply_stencil_op_to_pixels");
688 }
689}
void gl_problem(const GLcontext *ctx, const char *s)
Definition: context.c:1394
GLubyte GLstencil
Definition: types.h:208
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define GL_DECR
Definition: gl.h:462
#define GL_ZERO
Definition: gl.h:374
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define GL_INCR
Definition: gl.h:461
int GLint
Definition: gl.h:156
#define GL_REPLACE
Definition: gl.h:460
#define GL_INVERT
Definition: gl.h:435
#define GL_KEEP
Definition: gl.h:459
GLdouble n
Definition: glext.h:7729
GLenum GLint GLuint mask
Definition: glext.h:6028
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define STENCIL_ADDRESS(X, Y)
Definition: stencil.c:70
Definition: send.c:48

Referenced by gl_depth_stencil_pixels(), and gl_stencil_pixels().

◆ apply_stencil_op_to_span()

static void apply_stencil_op_to_span ( GLcontext ctx,
GLuint  n,
GLint  x,
GLint  y,
GLenum  oper,
GLubyte  mask[] 
)
static

Definition at line 207 of file stencil.c.

210{
211 GLint i;
212 GLstencil s, ref;
213 GLstencil wrtmask, invmask;
215
216 wrtmask = ctx->Stencil.WriteMask;
217 invmask = ~ctx->Stencil.WriteMask;
218 ref = ctx->Stencil.Ref;
220
221 switch (oper) {
222 case GL_KEEP:
223 /* do nothing */
224 break;
225 case GL_ZERO:
226 if (invmask==0) {
227 for (i=0;i<n;i++) {
228 if (mask[i]) {
229 stencil[i] = 0;
230 }
231 }
232 }
233 else {
234 for (i=0;i<n;i++) {
235 if (mask[i]) {
236 stencil[i] = stencil[i] & invmask;
237 }
238 }
239 }
240 break;
241 case GL_REPLACE:
242 if (invmask==0) {
243 for (i=0;i<n;i++) {
244 if (mask[i]) {
245 stencil[i] = ref;
246 }
247 }
248 }
249 else {
250 for (i=0;i<n;i++) {
251 if (mask[i]) {
252 s = stencil[i];
253 stencil[i] = (invmask & s ) | (wrtmask & ref);
254 }
255 }
256 }
257 break;
258 case GL_INCR:
259 if (invmask==0) {
260 for (i=0;i<n;i++) {
261 if (mask[i]) {
262 s = stencil[i];
263 if (s<0xff) {
264 stencil[i] = s+1;
265 }
266 }
267 }
268 }
269 else {
270 for (i=0;i<n;i++) {
271 if (mask[i]) {
272 /* VERIFY logic of adding 1 to a write-masked value */
273 s = stencil[i];
274 if (s<0xff) {
275 stencil[i] = (invmask & s) | (wrtmask & (s+1));
276 }
277 }
278 }
279 }
280 break;
281 case GL_DECR:
282 if (invmask==0) {
283 for (i=0;i<n;i++) {
284 if (mask[i]) {
285 s = stencil[i];
286 if (s>0) {
287 stencil[i] = s-1;
288 }
289 }
290 }
291 }
292 else {
293 for (i=0;i<n;i++) {
294 if (mask[i]) {
295 /* VERIFY logic of subtracting 1 to a write-masked value */
296 s = stencil[i];
297 if (s>0) {
298 stencil[i] = (invmask & s) | (wrtmask & (s-1));
299 }
300 }
301 }
302 }
303 break;
304 case GL_INVERT:
305 if (invmask==0) {
306 for (i=0;i<n;i++) {
307 if (mask[i]) {
308 s = stencil[i];
309 stencil[i] = ~s;
310 }
311 }
312 }
313 else {
314 for (i=0;i<n;i++) {
315 if (mask[i]) {
316 s = stencil[i];
317 stencil[i] = (invmask & s) | (wrtmask & ~s);
318 }
319 }
320 }
321 break;
322 default:
323 gl_problem(ctx, "Bad stencilop in apply_stencil_op_to_span");
324 }
325}
GLdouble s
Definition: gl.h:2039
GLint GLfloat GLint stencil
Definition: glext.h:6260

Referenced by gl_depth_stencil_span(), and gl_stencil_span().

◆ gl_alloc_stencil_buffer()

void gl_alloc_stencil_buffer ( GLcontext ctx)

Definition at line 975 of file stencil.c.

976{
977 GLuint buffersize = ctx->Buffer->Width * ctx->Buffer->Height;
978
979 /* deallocate current stencil buffer if present */
980 if (ctx->Buffer->Stencil) {
981 free(ctx->Buffer->Stencil);
982 ctx->Buffer->Stencil = NULL;
983 }
984
985 /* allocate new stencil buffer */
986 ctx->Buffer->Stencil = (GLstencil *) malloc(buffersize * sizeof(GLstencil));
987 if (!ctx->Buffer->Stencil) {
988 /* out of memory */
989 ctx->Stencil.Enabled = GL_FALSE;
990 gl_error( ctx, GL_OUT_OF_MEMORY, "gl_alloc_stencil_buffer" );
991 }
992}
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
void gl_error(GLcontext *ctx, GLenum error, const char *s)
Definition: context.c:1421
unsigned int GLuint
Definition: gl.h:159
#define GL_FALSE
Definition: gl.h:173
#define GL_OUT_OF_MEMORY
Definition: gl.h:699

Referenced by gl_ResizeBuffersMESA().

◆ gl_clear_stencil_buffer()

void gl_clear_stencil_buffer ( GLcontext ctx)

Definition at line 1001 of file stencil.c.

1002{
1003 if (ctx->Visual->StencilBits==0 || !ctx->Buffer->Stencil) {
1004 /* no stencil buffer */
1005 return;
1006 }
1007
1008 if (ctx->Scissor.Enabled) {
1009 /* clear scissor region only */
1010 GLint y;
1011 GLint width = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
1012 for (y=ctx->Buffer->Ymin; y<=ctx->Buffer->Ymax; y++) {
1013 GLstencil *ptr = STENCIL_ADDRESS( ctx->Buffer->Xmin, y );
1014 MEMSET( ptr, ctx->Stencil.Clear, width * sizeof(GLstencil) );
1015 }
1016 }
1017 else {
1018 /* clear whole stencil buffer */
1019 MEMSET( ctx->Buffer->Stencil, ctx->Stencil.Clear,
1020 ctx->Buffer->Width * ctx->Buffer->Height * sizeof(GLstencil) );
1021 }
1022}
Definition: bufpool.h:45
GLint GLint GLsizei width
Definition: gl.h:1546
#define MEMSET(DST, VAL, N)
Definition: macros.h:241
static PVOID ptr
Definition: dispmode.c:27

Referenced by gl_Clear().

◆ gl_ClearStencil()

void gl_ClearStencil ( GLcontext ctx,
GLint  s 
)

Definition at line 73 of file stencil.c.

74{
75 if (INSIDE_BEGIN_END(ctx)) {
76 gl_error( ctx, GL_INVALID_OPERATION, "glClearStencil" );
77 return;
78 }
79 ctx->Stencil.Clear = (GLstencil) s;
80}
#define GL_INVALID_OPERATION
Definition: gl.h:696
#define INSIDE_BEGIN_END(CTX)
Definition: macros.h:135

Referenced by execute_list(), and init_exec_pointers().

◆ gl_depth_stencil_pixels()

void gl_depth_stencil_pixels ( GLcontext ctx,
GLuint  n,
const GLint  x[],
const GLint  y[],
const GLdepth  z[],
GLubyte  mask[] 
)

Definition at line 882 of file stencil.c.

885{
886 if (ctx->Depth.Test==GL_FALSE) {
887 /*
888 * No depth buffer, just apply zpass stencil function to active pixels.
889 */
890 apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.ZPassFunc, mask );
891 }
892 else {
893 /*
894 * Perform depth buffering, then apply zpass or zfail stencil function.
895 */
896 GLubyte passmask[PB_SIZE], failmask[PB_SIZE], oldmask[PB_SIZE];
897 GLuint i;
898
899 /* init pass and fail masks to zero */
900 for (i=0;i<n;i++) {
901 passmask[i] = failmask[i] = 0;
902 oldmask[i] = mask[i];
903 }
904
905 /* apply the depth test */
906 if (ctx->Driver.DepthTestPixels)
907 (*ctx->Driver.DepthTestPixels)( ctx, n, x, y, z, mask );
908
909 /* set the stencil pass/fail flags according to result of depth test */
910 for (i=0;i<n;i++) {
911 if (oldmask[i]) {
912 if (mask[i]) {
913 passmask[i] = 1;
914 }
915 else {
916 failmask[i] = 1;
917 }
918 }
919 }
920
921 /* apply the pass and fail operations */
923 ctx->Stencil.ZFailFunc, failmask );
925 ctx->Stencil.ZPassFunc, passmask );
926 }
927
928}
unsigned char GLubyte
Definition: gl.h:157
GLdouble GLdouble z
Definition: glext.h:5874
#define PB_SIZE
Definition: pb.h:52
static void apply_stencil_op_to_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLenum oper, GLubyte mask[])
Definition: stencil.c:570

Referenced by gl_flush_pb().

◆ gl_depth_stencil_span()

void gl_depth_stencil_span ( GLcontext ctx,
GLuint  n,
GLint  x,
GLint  y,
const GLdepth  z[],
GLubyte  mask[] 
)

Definition at line 514 of file stencil.c.

517{
518 if (ctx->Depth.Test==GL_FALSE) {
519 /*
520 * No depth buffer, just apply zpass stencil function to active pixels.
521 */
522 apply_stencil_op_to_span( ctx, n, x, y, ctx->Stencil.ZPassFunc, mask );
523 }
524 else {
525 /*
526 * Perform depth buffering, then apply zpass or zfail stencil function.
527 */
528 GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
529 GLuint i;
530
531 /* init pass and fail masks to zero, copy mask[] to oldmask[] */
532 for (i=0;i<n;i++) {
533 passmask[i] = failmask[i] = 0;
534 oldmask[i] = mask[i];
535 }
536
537 /* apply the depth test */
538 if (ctx->Driver.DepthTestSpan)
539 (*ctx->Driver.DepthTestSpan)( ctx, n, x, y, z, mask );
540
541 /* set the stencil pass/fail flags according to result of depth test */
542 for (i=0;i<n;i++) {
543 if (oldmask[i]) {
544 if (mask[i]) {
545 passmask[i] = 1;
546 }
547 else {
548 failmask[i] = 1;
549 }
550 }
551 }
552
553 /* apply the pass and fail operations */
554 apply_stencil_op_to_span( ctx, n, x, y, ctx->Stencil.ZFailFunc, failmask );
555 apply_stencil_op_to_span( ctx, n, x, y, ctx->Stencil.ZPassFunc, passmask );
556 }
557}
#define MAX_WIDTH
Definition: config.h:130
static void apply_stencil_op_to_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLenum oper, GLubyte mask[])
Definition: stencil.c:207

Referenced by gl_write_color_span(), gl_write_index_span(), gl_write_monocolor_span(), gl_write_monoindex_span(), and gl_write_texture_span().

◆ gl_read_stencil_span()

void gl_read_stencil_span ( GLcontext ctx,
GLuint  n,
GLint  x,
GLint  y,
GLubyte  stencil[] 
)

Definition at line 938 of file stencil.c.

940{
941 GLstencil *s;
942
943 if (ctx->Buffer->Stencil) {
944 s = STENCIL_ADDRESS( x, y );
945 MEMCPY( stencil, s, n * sizeof(GLubyte) );
946 }
947}
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231

Referenced by copy_stencil_pixels(), and read_stencil_pixels().

◆ gl_stencil_pixels()

GLint gl_stencil_pixels ( GLcontext ctx,
GLuint  n,
const GLint  x[],
const GLint  y[],
GLubyte  mask[] 
)

Definition at line 702 of file stencil.c.

705{
706 GLubyte fail[PB_SIZE];
707 GLstencil r, s;
708 GLuint i;
709 GLint allfail = 0;
710
711 /*
712 * Perform stencil test. The results of this operation are stored
713 * in the fail[] array:
714 * IF fail[i] is non-zero THEN
715 * the stencil fail operator is to be applied
716 * ELSE
717 * the stencil fail operator is not to be applied
718 * ENDIF
719 */
720
721 switch (ctx->Stencil.Function) {
722 case GL_NEVER:
723 /* always fail */
724 for (i=0;i<n;i++) {
725 if (mask[i]) {
726 mask[i] = 0;
727 fail[i] = 1;
728 }
729 else {
730 fail[i] = 0;
731 }
732 }
733 allfail = 1;
734 break;
735 case GL_LESS:
736 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
737 for (i=0;i<n;i++) {
738 if (mask[i]) {
739 GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
740 s = *sptr & ctx->Stencil.ValueMask;
741 if (r < s) {
742 /* passed */
743 fail[i] = 0;
744 }
745 else {
746 fail[i] = 1;
747 mask[i] = 0;
748 }
749 }
750 else {
751 fail[i] = 0;
752 }
753 }
754 break;
755 case GL_LEQUAL:
756 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
757 for (i=0;i<n;i++) {
758 if (mask[i]) {
759 GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
760 s = *sptr & ctx->Stencil.ValueMask;
761 if (r <= s) {
762 /* pass */
763 fail[i] = 0;
764 }
765 else {
766 fail[i] = 1;
767 mask[i] = 0;
768 }
769 }
770 else {
771 fail[i] = 0;
772 }
773 }
774 break;
775 case GL_GREATER:
776 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
777 for (i=0;i<n;i++) {
778 if (mask[i]) {
779 GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
780 s = *sptr & ctx->Stencil.ValueMask;
781 if (r > s) {
782 /* passed */
783 fail[i] = 0;
784 }
785 else {
786 fail[i] = 1;
787 mask[i] = 0;
788 }
789 }
790 else {
791 fail[i] = 0;
792 }
793 }
794 break;
795 case GL_GEQUAL:
796 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
797 for (i=0;i<n;i++) {
798 if (mask[i]) {
799 GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
800 s = *sptr & ctx->Stencil.ValueMask;
801 if (r >= s) {
802 /* passed */
803 fail[i] = 0;
804 }
805 else {
806 fail[i] = 1;
807 mask[i] = 0;
808 }
809 }
810 else {
811 fail[i] = 0;
812 }
813 }
814 break;
815 case GL_EQUAL:
816 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
817 for (i=0;i<n;i++) {
818 if (mask[i]) {
819 GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
820 s = *sptr & ctx->Stencil.ValueMask;
821 if (r == s) {
822 /* passed */
823 fail[i] = 0;
824 }
825 else {
826 fail[i] = 1;
827 mask[i] = 0;
828 }
829 }
830 else {
831 fail[i] = 0;
832 }
833 }
834 break;
835 case GL_NOTEQUAL:
836 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
837 for (i=0;i<n;i++) {
838 if (mask[i]) {
839 GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
840 s = *sptr & ctx->Stencil.ValueMask;
841 if (r != s) {
842 /* passed */
843 fail[i] = 0;
844 }
845 else {
846 fail[i] = 1;
847 mask[i] = 0;
848 }
849 }
850 else {
851 fail[i] = 0;
852 }
853 }
854 break;
855 case GL_ALWAYS:
856 /* always pass */
857 for (i=0;i<n;i++) {
858 fail[i] = 0;
859 }
860 break;
861 default:
862 gl_problem(ctx, "Bad stencil func in gl_stencil_pixels");
863 return 0;
864 }
865
866 apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc, fail );
867
868 return (allfail) ? 0 : 1;
869}
#define GL_NEVER
Definition: gl.h:293
#define GL_ALWAYS
Definition: gl.h:300
#define GL_LESS
Definition: gl.h:294
#define GL_NOTEQUAL
Definition: gl.h:298
#define GL_LEQUAL
Definition: gl.h:296
#define GL_GEQUAL
Definition: gl.h:299
#define GL_GREATER
Definition: gl.h:297
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define GL_EQUAL
Definition: gl.h:295

Referenced by gl_flush_pb().

◆ gl_stencil_span()

GLint gl_stencil_span ( GLcontext ctx,
GLuint  n,
GLint  x,
GLint  y,
GLubyte  mask[] 
)

Definition at line 339 of file stencil.c.

341{
342 GLubyte fail[MAX_WIDTH];
343 GLint allfail = 0;
344 GLuint i;
345 GLstencil r, s;
347
349
350 /*
351 * Perform stencil test. The results of this operation are stored
352 * in the fail[] array:
353 * IF fail[i] is non-zero THEN
354 * the stencil fail operator is to be applied
355 * ELSE
356 * the stencil fail operator is not to be applied
357 * ENDIF
358 */
359 switch (ctx->Stencil.Function) {
360 case GL_NEVER:
361 /* always fail */
362 for (i=0;i<n;i++) {
363 if (mask[i]) {
364 mask[i] = 0;
365 fail[i] = 1;
366 }
367 else {
368 fail[i] = 0;
369 }
370 }
371 allfail = 1;
372 break;
373 case GL_LESS:
374 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
375 for (i=0;i<n;i++) {
376 if (mask[i]) {
377 s = stencil[i] & ctx->Stencil.ValueMask;
378 if (r < s) {
379 /* passed */
380 fail[i] = 0;
381 }
382 else {
383 fail[i] = 1;
384 mask[i] = 0;
385 }
386 }
387 else {
388 fail[i] = 0;
389 }
390 }
391 break;
392 case GL_LEQUAL:
393 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
394 for (i=0;i<n;i++) {
395 if (mask[i]) {
396 s = stencil[i] & ctx->Stencil.ValueMask;
397 if (r <= s) {
398 /* pass */
399 fail[i] = 0;
400 }
401 else {
402 fail[i] = 1;
403 mask[i] = 0;
404 }
405 }
406 else {
407 fail[i] = 0;
408 }
409 }
410 break;
411 case GL_GREATER:
412 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
413 for (i=0;i<n;i++) {
414 if (mask[i]) {
415 s = stencil[i] & ctx->Stencil.ValueMask;
416 if (r > s) {
417 /* passed */
418 fail[i] = 0;
419 }
420 else {
421 fail[i] = 1;
422 mask[i] = 0;
423 }
424 }
425 else {
426 fail[i] = 0;
427 }
428 }
429 break;
430 case GL_GEQUAL:
431 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
432 for (i=0;i<n;i++) {
433 if (mask[i]) {
434 s = stencil[i] & ctx->Stencil.ValueMask;
435 if (r >= s) {
436 /* passed */
437 fail[i] = 0;
438 }
439 else {
440 fail[i] = 1;
441 mask[i] = 0;
442 }
443 }
444 else {
445 fail[i] = 0;
446 }
447 }
448 break;
449 case GL_EQUAL:
450 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
451 for (i=0;i<n;i++) {
452 if (mask[i]) {
453 s = stencil[i] & ctx->Stencil.ValueMask;
454 if (r == s) {
455 /* passed */
456 fail[i] = 0;
457 }
458 else {
459 fail[i] = 1;
460 mask[i] = 0;
461 }
462 }
463 else {
464 fail[i] = 0;
465 }
466 }
467 break;
468 case GL_NOTEQUAL:
469 r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
470 for (i=0;i<n;i++) {
471 if (mask[i]) {
472 s = stencil[i] & ctx->Stencil.ValueMask;
473 if (r != s) {
474 /* passed */
475 fail[i] = 0;
476 }
477 else {
478 fail[i] = 1;
479 mask[i] = 0;
480 }
481 }
482 else {
483 fail[i] = 0;
484 }
485 }
486 break;
487 case GL_ALWAYS:
488 /* always pass */
489 for (i=0;i<n;i++) {
490 fail[i] = 0;
491 }
492 break;
493 default:
494 gl_problem(ctx, "Bad stencil func in gl_stencil_span");
495 return 0;
496 }
497
498 apply_stencil_op_to_span( ctx, n, x, y, ctx->Stencil.FailFunc, fail );
499
500 return (allfail) ? 0 : 1;
501}

Referenced by gl_write_color_span(), gl_write_index_span(), gl_write_monocolor_span(), gl_write_monoindex_span(), and gl_write_texture_span().

◆ gl_StencilFunc()

void gl_StencilFunc ( GLcontext ctx,
GLenum  func,
GLint  ref,
GLuint  mask 
)

Definition at line 84 of file stencil.c.

85{
86 GLint maxref;
87
88 if (INSIDE_BEGIN_END(ctx)) {
89 gl_error( ctx, GL_INVALID_OPERATION, "glStencilFunc" );
90 return;
91 }
92
93 switch (func) {
94 case GL_NEVER:
95 case GL_LESS:
96 case GL_LEQUAL:
97 case GL_GREATER:
98 case GL_GEQUAL:
99 case GL_EQUAL:
100 case GL_NOTEQUAL:
101 case GL_ALWAYS:
102 ctx->Stencil.Function = func;
103 break;
104 default:
105 gl_error( ctx, GL_INVALID_ENUM, "glStencilFunc" );
106 return;
107 }
108
109 maxref = (1 << STENCIL_BITS) - 1;
110 ctx->Stencil.Ref = CLAMP( ref, 0, maxref );
111 ctx->Stencil.ValueMask = mask;
112}
#define STENCIL_BITS
Definition: config.h:152
#define GL_INVALID_ENUM
Definition: gl.h:694
GLenum func
Definition: glext.h:6028
#define CLAMP(f, min, max)
Definition: tif_color.c:177

Referenced by execute_list(), and init_exec_pointers().

◆ gl_StencilMask()

void gl_StencilMask ( GLcontext ctx,
GLuint  mask 
)

Definition at line 116 of file stencil.c.

117{
118 if (INSIDE_BEGIN_END(ctx)) {
119 gl_error( ctx, GL_INVALID_OPERATION, "glStencilMask" );
120 return;
121 }
122 ctx->Stencil.WriteMask = (GLstencil) mask;
123}

Referenced by execute_list(), and init_exec_pointers().

◆ gl_StencilOp()

void gl_StencilOp ( GLcontext ctx,
GLenum  fail,
GLenum  zfail,
GLenum  zpass 
)

Definition at line 127 of file stencil.c.

128{
129 if (INSIDE_BEGIN_END(ctx)) {
130 gl_error( ctx, GL_INVALID_OPERATION, "glStencilOp" );
131 return;
132 }
133 switch (fail) {
134 case GL_KEEP:
135 case GL_ZERO:
136 case GL_REPLACE:
137 case GL_INCR:
138 case GL_DECR:
139 case GL_INVERT:
140 ctx->Stencil.FailFunc = fail;
141 break;
142 default:
143 gl_error( ctx, GL_INVALID_ENUM, "glStencilOp" );
144 return;
145 }
146 switch (zfail) {
147 case GL_KEEP:
148 case GL_ZERO:
149 case GL_REPLACE:
150 case GL_INCR:
151 case GL_DECR:
152 case GL_INVERT:
153 ctx->Stencil.ZFailFunc = zfail;
154 break;
155 default:
156 gl_error( ctx, GL_INVALID_ENUM, "glStencilOp" );
157 return;
158 }
159 switch (zpass) {
160 case GL_KEEP:
161 case GL_ZERO:
162 case GL_REPLACE:
163 case GL_INCR:
164 case GL_DECR:
165 case GL_INVERT:
166 ctx->Stencil.ZPassFunc = zpass;
167 break;
168 default:
169 gl_error( ctx, GL_INVALID_ENUM, "glStencilOp" );
170 return;
171 }
172}

Referenced by execute_list(), and init_exec_pointers().

◆ gl_write_stencil_span()

void gl_write_stencil_span ( GLcontext ctx,
GLuint  n,
GLint  x,
GLint  y,
const GLubyte  stencil[] 
)

Definition at line 957 of file stencil.c.

960{
961 GLstencil *s;
962
963 if (ctx->Buffer->Stencil) {
964 s = STENCIL_ADDRESS( x, y );
965 MEMCPY( s, stencil, n * sizeof(GLubyte) );
966 }
967}

Referenced by copy_stencil_pixels(), draw_stencil_pixels(), and gl_write_zoomed_stencil_span().