1 /* $Id: depth.c,v 1.11 1997/07/24 01:24:45 brianp Exp $ */
4 * Mesa 3-D graphics library
6 * Copyright (C) 1995-1997 Brian Paul
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * Revision 1.11 1997/07/24 01:24:45 brianp
27 * changed precompiled header symbol from PCH to PC_HEADER
29 * Revision 1.10 1997/05/28 03:24:22 brianp
30 * added precompiled header (PCH) support
32 * Revision 1.9 1997/04/20 19:54:15 brianp
33 * replaced abort() with gl_problem()
35 * Revision 1.8 1997/02/27 19:58:52 brianp
36 * don't try to clear depth buffer if there isn't one
38 * Revision 1.7 1997/01/31 23:33:08 brianp
39 * replaced calloc with malloc in gl_alloc_depth_buffer()
41 * Revision 1.6 1996/11/04 01:42:07 brianp
42 * multiply Viewport.Sz and .Tz by DEPTH_SCALE
44 * Revision 1.5 1996/10/09 03:07:25 brianp
45 * replaced malloc with calloc in gl_alloc_depth_buffer()
47 * Revision 1.4 1996/09/27 01:24:58 brianp
48 * added missing default cases to switches
50 * Revision 1.3 1996/09/19 00:54:05 brianp
51 * added missing returns after some gl_error() calls
53 * Revision 1.2 1996/09/15 14:19:16 brianp
54 * now use GLframebuffer and GLvisual
56 * Revision 1.1 1996/09/13 01:38:16 brianp
63 * Depth buffer functions
81 /**********************************************************************/
82 /***** API Functions *****/
83 /**********************************************************************/
87 void gl_ClearDepth( GLcontext
* ctx
, GLclampd depth
)
89 if (INSIDE_BEGIN_END(ctx
)) {
90 gl_error( ctx
, GL_INVALID_OPERATION
, "glClearDepth" );
93 ctx
->Depth
.Clear
= (GLfloat
) CLAMP( depth
, 0.0, 1.0 );
98 void gl_DepthFunc( GLcontext
* ctx
, GLenum func
)
100 if (INSIDE_BEGIN_END(ctx
)) {
101 gl_error( ctx
, GL_INVALID_OPERATION
, "glDepthFunc" );
107 case GL_LESS
: /* (default) pass if incoming z < stored z */
114 ctx
->Depth
.Func
= func
;
115 ctx
->NewState
|= NEW_RASTER_OPS
;
118 gl_error( ctx
, GL_INVALID_ENUM
, "glDepth.Func" );
124 void gl_DepthMask( GLcontext
* ctx
, GLboolean flag
)
126 if (INSIDE_BEGIN_END(ctx
)) {
127 gl_error( ctx
, GL_INVALID_OPERATION
, "glDepthMask" );
132 * GL_TRUE indicates depth buffer writing is enabled (default)
133 * GL_FALSE indicates depth buffer writing is disabled
135 ctx
->Depth
.Mask
= flag
;
136 ctx
->NewState
|= NEW_RASTER_OPS
;
141 void gl_DepthRange( GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
144 * nearval - specifies mapping of the near clipping plane to window
145 * coordinates, default is 0
146 * farval - specifies mapping of the far clipping plane to window
147 * coordinates, default is 1
149 * After clipping and div by w, z coords are in -1.0 to 1.0,
150 * corresponding to near and far clipping planes. glDepthRange
151 * specifies a linear mapping of the normalized z coords in
152 * this range to window z coords.
157 if (INSIDE_BEGIN_END(ctx
)) {
158 gl_error( ctx
, GL_INVALID_OPERATION
, "glDepthRange" );
162 n
= (GLfloat
) CLAMP( nearval
, 0.0, 1.0 );
163 f
= (GLfloat
) CLAMP( farval
, 0.0, 1.0 );
165 ctx
->Viewport
.Near
= n
;
166 ctx
->Viewport
.Far
= f
;
167 ctx
->Viewport
.Sz
= DEPTH_SCALE
* ((f
- n
) / 2.0);
168 ctx
->Viewport
.Tz
= DEPTH_SCALE
* ((f
- n
) / 2.0 + n
);
173 /**********************************************************************/
174 /***** Depth Testing Functions *****/
175 /**********************************************************************/
179 * Depth test horizontal spans of fragments. These functions are called
180 * via ctx->Driver.depth_test_span only.
182 * Input: n - number of pixels in the span
183 * x, y - location of leftmost pixel in span in window coords
184 * z - array [n] of integer depth values
185 * In/Out: mask - array [n] of flags (1=draw pixel, 0=don't draw)
186 * Return: number of pixels which passed depth test
191 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
193 GLuint
gl_depth_test_span_generic( GLcontext
* ctx
,
194 GLuint n
, GLint x
, GLint y
,
198 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
203 /* switch cases ordered from most frequent to less frequent */
204 switch (ctx
->Depth
.Func
) {
206 if (ctx
->Depth
.Mask
) {
207 /* Update Z buffer */
208 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
223 /* Don't update Z buffer */
224 for (i
=0; i
<n
; i
++,zptr
++,m
++) {
238 if (ctx
->Depth
.Mask
) {
239 /* Update Z buffer */
240 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
253 /* Don't update Z buffer */
254 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
268 if (ctx
->Depth
.Mask
) {
269 /* Update Z buffer */
270 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
283 /* Don't update Z buffer */
284 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
298 if (ctx
->Depth
.Mask
) {
299 /* Update Z buffer */
300 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
313 /* Don't update Z buffer */
314 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
328 if (ctx
->Depth
.Mask
) {
329 /* Update Z buffer */
330 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
343 /* Don't update Z buffer */
344 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
358 if (ctx
->Depth
.Mask
) {
359 /* Update Z buffer */
360 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
373 /* Don't update Z buffer */
374 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
388 if (ctx
->Depth
.Mask
) {
389 /* Update Z buffer */
390 for (i
=0;i
<n
;i
++,zptr
++,m
++) {
398 /* Don't update Z buffer or mask */
408 gl_problem(ctx
, "Bad depth func in gl_depth_test_span_generic");
417 * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
419 GLuint
gl_depth_test_span_less( GLcontext
* ctx
,
420 GLuint n
, GLint x
, GLint y
, const GLdepth z
[],
423 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
427 for (i
=0; i
<n
; i
++) {
429 if (z
[i
] < zptr
[i
]) {
445 * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
447 GLuint
gl_depth_test_span_greater( GLcontext
* ctx
,
448 GLuint n
, GLint x
, GLint y
,
452 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
456 for (i
=0; i
<n
; i
++) {
458 if (z
[i
] > zptr
[i
]) {
475 * Depth test an array of randomly positioned fragments.
479 #define ZADDR_SETUP GLdepth *depthbuffer = ctx->Buffer->Depth; \
480 GLint width = ctx->Buffer->Width;
482 #define ZADDR( X, Y ) (depthbuffer + (Y) * width + (X) )
487 * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
489 void gl_depth_test_pixels_generic( GLcontext
* ctx
,
490 GLuint n
, const GLint x
[], const GLint y
[],
491 const GLdepth z
[], GLubyte mask
[] )
493 register GLdepth
*zptr
;
496 /* switch cases ordered from most frequent to less frequent */
497 switch (ctx
->Depth
.Func
) {
499 if (ctx
->Depth
.Mask
) {
500 /* Update Z buffer */
501 for (i
=0; i
<n
; i
++) {
503 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
516 /* Don't update Z buffer */
517 for (i
=0; i
<n
; i
++) {
519 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
532 if (ctx
->Depth
.Mask
) {
533 /* Update Z buffer */
534 for (i
=0; i
<n
; i
++) {
536 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
549 /* Don't update Z buffer */
550 for (i
=0; i
<n
; i
++) {
552 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
565 if (ctx
->Depth
.Mask
) {
566 /* Update Z buffer */
567 for (i
=0; i
<n
; i
++) {
569 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
582 /* Don't update Z buffer */
583 for (i
=0; i
<n
; i
++) {
585 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
598 if (ctx
->Depth
.Mask
) {
599 /* Update Z buffer */
600 for (i
=0; i
<n
; i
++) {
602 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
615 /* Don't update Z buffer */
616 for (i
=0; i
<n
; i
++) {
618 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
631 if (ctx
->Depth
.Mask
) {
632 /* Update Z buffer */
633 for (i
=0; i
<n
; i
++) {
635 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
648 /* Don't update Z buffer */
649 for (i
=0; i
<n
; i
++) {
651 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
664 if (ctx
->Depth
.Mask
) {
665 /* Update Z buffer */
666 for (i
=0; i
<n
; i
++) {
668 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
681 /* Don't update Z buffer */
682 for (i
=0; i
<n
; i
++) {
684 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
697 if (ctx
->Depth
.Mask
) {
698 /* Update Z buffer */
699 for (i
=0; i
<n
; i
++) {
701 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
707 /* Don't update Z buffer or mask */
711 /* depth test never passes */
717 gl_problem(ctx
, "Bad depth func in gl_depth_test_pixels_generic");
724 * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
726 void gl_depth_test_pixels_less( GLcontext
* ctx
,
727 GLuint n
, const GLint x
[], const GLint y
[],
728 const GLdepth z
[], GLubyte mask
[] )
733 for (i
=0; i
<n
; i
++) {
735 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
750 * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
752 void gl_depth_test_pixels_greater( GLcontext
* ctx
,
753 GLuint n
, const GLint x
[], const GLint y
[],
754 const GLdepth z
[], GLubyte mask
[] )
759 for (i
=0; i
<n
; i
++) {
761 zptr
= Z_ADDRESS(ctx
,x
[i
],y
[i
]);
777 /**********************************************************************/
778 /***** Read Depth Buffer *****/
779 /**********************************************************************/
783 * Return a span of depth values from the depth buffer as floats in [0,1].
784 * This function is only called through Driver.read_depth_span_float()
785 * Input: n - how many pixels
786 * x,y - location of first pixel
787 * Output: depth - the array of depth values
789 void gl_read_depth_span_float( GLcontext
* ctx
,
790 GLuint n
, GLint x
, GLint y
, GLfloat depth
[] )
796 scale
= 1.0F
/ DEPTH_SCALE
;
798 if (ctx
->Buffer
->Depth
) {
799 zptr
= Z_ADDRESS( ctx
, x
, y
);
801 depth
[i
] = (GLfloat
) zptr
[i
] * scale
;
813 * Return a span of depth values from the depth buffer as integers in
815 * This function is only called through Driver.read_depth_span_int()
816 * Input: n - how many pixels
817 * x,y - location of first pixel
818 * Output: depth - the array of depth values
820 void gl_read_depth_span_int( GLcontext
* ctx
,
821 GLuint n
, GLint x
, GLint y
, GLdepth depth
[] )
823 if (ctx
->Buffer
->Depth
) {
824 GLdepth
*zptr
= Z_ADDRESS( ctx
, x
, y
);
825 MEMCPY( depth
, zptr
, n
* sizeof(GLdepth
) );
837 /**********************************************************************/
838 /***** Allocate and Clear Depth Buffer *****/
839 /**********************************************************************/
844 * Allocate a new depth buffer. If there's already a depth buffer allocated
845 * it will be free()'d. The new depth buffer will be uniniitalized.
846 * This function is only called through Driver.alloc_depth_buffer.
848 void gl_alloc_depth_buffer( GLcontext
* ctx
)
850 /* deallocate current depth buffer if present */
851 if (ctx
->Buffer
->Depth
) {
852 free(ctx
->Buffer
->Depth
);
853 ctx
->Buffer
->Depth
= NULL
;
856 /* allocate new depth buffer, but don't initialize it */
857 ctx
->Buffer
->Depth
= (GLdepth
*) malloc( ctx
->Buffer
->Width
858 * ctx
->Buffer
->Height
860 if (!ctx
->Buffer
->Depth
) {
862 ctx
->Depth
.Test
= GL_FALSE
;
863 gl_error( ctx
, GL_OUT_OF_MEMORY
, "Couldn't allocate depth buffer" );
871 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
873 * This function is only called through Driver.clear_depth_buffer.
875 void gl_clear_depth_buffer( GLcontext
* ctx
)
877 GLdepth clear_value
= (GLdepth
) (ctx
->Depth
.Clear
* DEPTH_SCALE
);
879 if (ctx
->Visual
->DepthBits
==0 || !ctx
->Buffer
->Depth
) {
880 /* no depth buffer */
884 /* The loops in this function have been written so the IRIX 5.3
885 * C compiler can unroll them. Hopefully other compilers can too!
888 if (ctx
->Scissor
.Enabled
) {
889 /* only clear scissor region */
891 for (y
=ctx
->Buffer
->Ymin
; y
<=ctx
->Buffer
->Ymax
; y
++) {
892 GLdepth
*d
= Z_ADDRESS( ctx
, ctx
->Buffer
->Xmin
, y
);
893 GLint n
= ctx
->Buffer
->Xmax
- ctx
->Buffer
->Xmin
+ 1;
901 /* clear whole buffer */
902 GLdepth
*d
= ctx
->Buffer
->Depth
;
903 GLint n
= ctx
->Buffer
->Width
* ctx
->Buffer
->Height
;
905 d
[0] = clear_value
; d
[1] = clear_value
;
906 d
[2] = clear_value
; d
[3] = clear_value
;
907 d
[4] = clear_value
; d
[5] = clear_value
;
908 d
[6] = clear_value
; d
[7] = clear_value
;
909 d
[8] = clear_value
; d
[9] = clear_value
;
910 d
[10] = clear_value
; d
[11] = clear_value
;
911 d
[12] = clear_value
; d
[13] = clear_value
;
912 d
[14] = clear_value
; d
[15] = clear_value
;