home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src / depth.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  19KB  |  901 lines

  1. /* $Id: depth.c,v 1.21 1996/05/15 18:20:01 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995-1996  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  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.
  12.  *
  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.
  17.  *
  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.
  21.  */
  22.  
  23.  
  24. /*
  25. $Log: depth.c,v $
  26.  * Revision 1.21  1996/05/15  18:20:01  brianp
  27.  * added branch-less Z testing
  28.  *
  29.  * Revision 1.20  1996/05/01  15:47:48  brianp
  30.  * added gl_read_depth_span_int()
  31.  *
  32.  * Revision 1.19  1996/04/25  20:39:21  brianp
  33.  * added comments about DD.<depth function> calling conventions
  34.  *
  35.  * Revision 1.18  1996/03/21  22:47:20  brianp
  36.  * removed obsolete comments
  37.  *
  38.  * Revision 1.17  1996/01/22  15:26:29  brianp
  39.  * set CC.NewState in glDepthFunc() and glDepthMask()
  40.  *
  41.  * Revision 1.16  1996/01/12  22:30:52  brianp
  42.  * use the Z_ADDRESS() macro
  43.  *
  44.  * Revision 1.15  1995/12/19  16:41:48  brianp
  45.  * optimized 16-bit clear for more clear values
  46.  *
  47.  * Revision 1.14  1995/12/18  17:25:05  brianp
  48.  * use new GLdepth datatype
  49.  *
  50.  * Revision 1.13  1995/11/30  00:18:54  brianp
  51.  * manually unrolled loop in gl_clear_depth_buffer()
  52.  *
  53.  * Revision 1.12  1995/09/22  21:53:35  brianp
  54.  * optimized gl_clear_depth_buffer for loop unrolling
  55.  *
  56.  * Revision 1.11  1995/07/11  15:10:38  brianp
  57.  * fixed bug in gl_depth_test_span when func=GL_ALWAYS and DepthMask=GL_FALSE
  58.  *
  59.  * Revision 1.10  1995/06/21  15:09:17  brianp
  60.  * added a comment to gl_clear_depth_buffer
  61.  *
  62.  * Revision 1.9  1995/06/15  21:08:05  brianp
  63.  * fixed bug in gl_read_depth_span() per Asif Khan
  64.  *
  65.  * Revision 1.8  1995/06/09  20:20:50  brianp
  66.  * renamed gl_depth_test() as gl_depth_test_span() and return 'passed' count
  67.  *
  68.  * Revision 1.7  1995/05/22  21:02:41  brianp
  69.  * Release 1.2
  70.  *
  71.  * Revision 1.6  1995/05/12  19:24:13  brianp
  72.  * replaced CC.Mode!=0 with INSIDE_BEGIN_END
  73.  *
  74.  * Revision 1.5  1995/04/19  13:48:18  brianp
  75.  * renamed occurances of near and far for SCO x86 Unix
  76.  *
  77.  * Revision 1.4  1995/03/09  21:34:01  brianp
  78.  * removed #include stdio.h
  79.  *
  80.  * Revision 1.3  1995/03/04  19:29:44  brianp
  81.  * 1.1 beta revision
  82.  *
  83.  * Revision 1.2  1995/02/27  22:48:39  brianp
  84.  * modified for PB
  85.  *
  86.  * Revision 1.1  1995/02/24  14:20:28  brianp
  87.  * Initial revision
  88.  *
  89.  */
  90.  
  91.  
  92. /*
  93.  * Depth buffer functions
  94.  */
  95.  
  96.  
  97.  
  98. #include <stdlib.h>
  99. #include <string.h>
  100. #include "context.h"
  101. #include "depth.h"
  102. #include "list.h"
  103. #include "macros.h"
  104.  
  105.  
  106.  
  107.  
  108. void glClearDepth( GLclampd depth )
  109. {
  110.    if (CC.CompileFlag) {
  111.       gl_save_cleardepth( (GLfloat) depth );
  112.    }
  113.    if (CC.ExecuteFlag) {
  114.       if (INSIDE_BEGIN_END) {
  115.      gl_error( GL_INVALID_OPERATION, "glClearDepth" );
  116.       }
  117.       CC.Depth.Clear = (GLfloat) CLAMP( depth, 0.0, 1.0 );
  118.    }
  119. }
  120.  
  121.  
  122.  
  123. void glDepthFunc( GLenum func )
  124. {
  125.    if (CC.CompileFlag) {
  126.       gl_save_depthfunc( func );
  127.    }
  128.  
  129.    if (CC.ExecuteFlag) {
  130.       if (INSIDE_BEGIN_END) {
  131.      gl_error( GL_INVALID_OPERATION, "glDepthFunc" );
  132.       }
  133.  
  134.       switch (func) {
  135.      case GL_NEVER:
  136.      case GL_LESS:    /* (default) pass if incoming z < stored z */
  137.      case GL_GEQUAL:
  138.      case GL_LEQUAL:
  139.      case GL_GREATER:
  140.      case GL_NOTEQUAL:
  141.      case GL_EQUAL:
  142.      case GL_ALWAYS:
  143.         CC.Depth.Func = func;
  144.             CC.NewState = GL_TRUE;
  145.         break;
  146.      default:
  147.         gl_error( GL_INVALID_ENUM, "glDepth.Func" );
  148.       }
  149.    }
  150. }
  151.  
  152.  
  153.  
  154. void glDepthMask( GLboolean flag )
  155. {
  156.    if (CC.CompileFlag) {
  157.       gl_save_depthmask( flag );
  158.    }
  159.    if (CC.ExecuteFlag) {
  160.       if (INSIDE_BEGIN_END) {
  161.      gl_error( GL_INVALID_OPERATION, "glDepthMask" );
  162.       }
  163.  
  164.       /*
  165.        * GL_TRUE indicates depth buffer writing is enabled (default)
  166.        * GL_FALSE indicates depth buffer writing is disabled
  167.        */
  168.       CC.Depth.Mask = flag;
  169.       CC.NewState = GL_TRUE;
  170.    }
  171. }
  172.  
  173.  
  174.  
  175. void glDepthRange( GLclampd nearval, GLclampd farval )
  176. {
  177.    /*
  178.     * nearval - specifies mapping of the near clipping plane to window
  179.     *   coordinates, default is 0
  180.     * farval - specifies mapping of the far clipping plane to window
  181.     *   coordinates, default is 1
  182.     *
  183.     * After clipping and div by w, z coords are in -1.0 to 1.0,
  184.     * corresponding to near and far clipping planes.  glDepthRange
  185.     * specifies a linear mapping of the normalized z coords in
  186.     * this range to window z coords.
  187.     */
  188.  
  189.    if (CC.CompileFlag) {
  190.       gl_save_depthrange( nearval, farval );
  191.    }
  192.    if (CC.ExecuteFlag) {
  193.       GLfloat n, f;
  194.  
  195.       if (INSIDE_BEGIN_END) {
  196.      gl_error( GL_INVALID_OPERATION, "glDepthRange" );
  197.       }
  198.  
  199.       n = (GLfloat) CLAMP( nearval, 0.0, 1.0 );
  200.       f = (GLfloat) CLAMP( farval, 0.0, 1.0 );
  201.  
  202.       CC.Viewport.Near = n;
  203.       CC.Viewport.Far = f;
  204.       CC.Viewport.Sz = (f - n) / 2.0;
  205.       CC.Viewport.Tz = (f - n) / 2.0 + n;
  206.    }
  207. }
  208.  
  209.  
  210.  
  211. /*
  212.  * Apply depth buffer test to a horizontal span of pixels:
  213.  *
  214.  * FOREACH pixel[i] in the span DO
  215.  *    IF mask[i]!=0 THEN
  216.  *       IF depth test passes THEN
  217.  *          update z value
  218.  *       ELSE
  219.  *          mask[i] = 0;
  220.  *       ENDIF
  221.  *    ENDIF
  222.  * ENDDO
  223.  *
  224.  * This function is only called through DD.depth_test_span.
  225.  *
  226.  * Input:  n - number of pixels in the span
  227.  *         x, y - location of leftmost pixel in span in window coords
  228.  *         z - array [n] of integer depth values
  229.  * In/Out:  mask - array [n] of flags (1=draw pixel, 0=don't draw) 
  230.  * Return:  number of pixels which passed depth test
  231.  */
  232. GLuint gl_depth_test_span( GLuint n, GLint x, GLint y, const GLdepth z[],
  233.                GLubyte mask[] )
  234. {
  235.    GLdepth *zptr = Z_ADDRESS( x, y );
  236.    GLubyte *m = mask;
  237.    GLuint i;
  238.    GLuint passed = 0;
  239.  
  240.    /* switch cases ordered from most frequent to less frequent */
  241.    switch (CC.Depth.Func) {
  242.       case GL_LESS:
  243.          if (CC.Depth.Mask) {
  244.         /* Update Z buffer */
  245. #ifdef SAFE
  246.         for (i=0; i<n; i++,zptr++,m++) {
  247.            if (*m) {
  248.           if (z[i] < *zptr) {
  249.              /* pass */
  250.              *zptr = z[i];
  251.              passed++;
  252.           }
  253.           else {
  254.              /* fail */
  255.              *m = 0;
  256.           }
  257.            }
  258.         }
  259. #else
  260.             /* OPTIMIZED: no branches */
  261.         for (i=0; i<n; i++) {
  262.                GLint newz = z[i];
  263.                GLint oldz = zptr[i];
  264.                GLint p = mask[i] & (newz < oldz);        /* 0 or 1 */
  265.                mask[i] = p;
  266.                passed += p;
  267.                p = 0 - p;                                /* 0 or ~0 */
  268.                zptr[i] = (oldz & ~p) | (newz & p);
  269.         }
  270. #endif
  271.      }
  272.      else {
  273.         /* Don't update Z buffer */
  274. #ifdef SAFE
  275.         for (i=0; i<n; i++,zptr++,m++) {
  276.            if (*m) {
  277.           if (z[i] < *zptr) {
  278.              /* pass */
  279.              passed++;
  280.           }
  281.           else {
  282.              *m = 0;
  283.           }
  284.            }
  285.         }
  286. #else
  287.             /* OPTIMIZED: no branches */
  288.         for (i=0; i<n; i++) {
  289.                GLint p = mask[i] & (z[i] < zptr[i]);
  290.                mask[i] = p;
  291.                passed += p;
  292.         }
  293. #endif
  294.      }
  295.      break;
  296.       case GL_LEQUAL:
  297.      if (CC.Depth.Mask) {
  298.         /* Update Z buffer */
  299.         for (i=0;i<n;i++,zptr++,m++) {
  300.            if (*m) {
  301.           if (z[i] <= *zptr) {
  302.              *zptr = z[i];
  303.              passed++;
  304.           }
  305.           else {
  306.              *m = 0;
  307.           }
  308.            }
  309.         }
  310.      }
  311.      else {
  312.         /* Don't update Z buffer */
  313.         for (i=0;i<n;i++,zptr++,m++) {
  314.            if (*m) {
  315.           if (z[i] <= *zptr) {
  316.              /* pass */
  317.              passed++;
  318.           }
  319.           else {
  320.              *m = 0;
  321.           }
  322.            }
  323.         }
  324.      }
  325.      break;
  326.       case GL_GEQUAL:
  327.      if (CC.Depth.Mask) {
  328.         /* Update Z buffer */
  329.         for (i=0;i<n;i++,zptr++,m++) {
  330.            if (*m) {
  331.           if (z[i] >= *zptr) {
  332.              *zptr = z[i];
  333.              passed++;
  334.           }
  335.           else {
  336.              *m = 0;
  337.           }
  338.            }
  339.         }
  340.      }
  341.      else {
  342.         /* Don't update Z buffer */
  343.         for (i=0;i<n;i++,zptr++,m++) {
  344.            if (*m) {
  345.           if (z[i] >= *zptr) {
  346.              /* pass */
  347.              passed++;
  348.           }
  349.           else {
  350.              *m = 0;
  351.           }
  352.            }
  353.         }
  354.      }
  355.      break;
  356.       case GL_GREATER:
  357.      if (CC.Depth.Mask) {
  358.         /* Update Z buffer */
  359.         for (i=0;i<n;i++,zptr++,m++) {
  360.            if (*m) {
  361.           if (z[i] > *zptr) {
  362.              *zptr = z[i];
  363.              passed++;
  364.           }
  365.           else {
  366.              *m = 0;
  367.           }
  368.            }
  369.         }
  370.      }
  371.      else {
  372.         /* Don't update Z buffer */
  373.         for (i=0;i<n;i++,zptr++,m++) {
  374.            if (*m) {
  375.           if (z[i] > *zptr) {
  376.              /* pass */
  377.              passed++;
  378.           }
  379.           else {
  380.              *m = 0;
  381.           }
  382.            }
  383.         }
  384.      }
  385.      break;
  386.       case GL_NOTEQUAL:
  387.      if (CC.Depth.Mask) {
  388.         /* Update Z buffer */
  389.         for (i=0;i<n;i++,zptr++,m++) {
  390.            if (*m) {
  391.           if (z[i] != *zptr) {
  392.              *zptr = z[i];
  393.              passed++;
  394.           }
  395.           else {
  396.              *m = 0;
  397.           }
  398.            }
  399.         }
  400.      }
  401.      else {
  402.         /* Don't update Z buffer */
  403.         for (i=0;i<n;i++,zptr++,m++) {
  404.            if (*m) {
  405.           if (z[i] != *zptr) {
  406.              /* pass */
  407.              passed++;
  408.           }
  409.           else {
  410.              *m = 0;
  411.           }
  412.            }
  413.         }
  414.      }
  415.      break;
  416.       case GL_EQUAL:
  417.      if (CC.Depth.Mask) {
  418.         /* Update Z buffer */
  419.         for (i=0;i<n;i++,zptr++,m++) {
  420.            if (*m) {
  421.           if (z[i] == *zptr) {
  422.              *zptr = z[i];
  423.              passed++;
  424.           }
  425.           else {
  426.              *m =0;
  427.           }
  428.            }
  429.         }
  430.      }
  431.      else {
  432.         /* Don't update Z buffer */
  433.         for (i=0;i<n;i++,zptr++,m++) {
  434.            if (*m) {
  435.           if (z[i] == *zptr) {
  436.              /* pass */
  437.              passed++;
  438.           }
  439.           else {
  440.              *m =0;
  441.           }
  442.            }
  443.         }
  444.      }
  445.      break;
  446.       case GL_ALWAYS:
  447.      if (CC.Depth.Mask) {
  448.         /* Update Z buffer */
  449. #ifdef SAFE
  450.         for (i=0;i<n;i++,zptr++,m++) {
  451.            if (*m) {
  452.           *zptr = z[i];
  453.           passed++;
  454.            }
  455.         }
  456. #else
  457.             /* OPTIMIZED: no branches */
  458.         for (i=0;i<n;i++) {
  459.                GLint p = 0 - mask[i];   /* 0 or ~0 */
  460.                zptr[i] = (zptr[i] & ~p) | (z[i] & p);
  461.                passed += mask[i];
  462.         }
  463. #endif
  464.      }
  465.      else {
  466.         /* Don't update Z buffer or mask */
  467.         passed = n;
  468.      }
  469.      break;
  470.       case GL_NEVER:
  471.      for (i=0;i<n;i++) {
  472.         mask[i] = 0;
  473.      }
  474.      break;
  475.    } /*switch*/
  476.  
  477.    return passed;
  478. }
  479.  
  480.  
  481.  
  482.  
  483. #define ZADDR_SETUP   GLdepth *depthbuffer = CC.DepthBuffer; \
  484.                       GLint width = CC.BufferWidth;
  485.  
  486. #define ZADDR( X, Y )   (depthbuffer + (Y) * width + (X) )
  487.  
  488.  
  489.  
  490. /*
  491.  * Perform depth testing on an array of pixels.
  492.  * This function is only called through DD.depth_test_pixels.
  493.  */
  494. void gl_depth_test_pixels( GLuint n, const GLint x[], const GLint y[],
  495.                const GLdepth z[], GLubyte mask[] )
  496. {
  497.    register GLdepth *zptr;
  498.    register GLuint i;
  499.  
  500.    /* switch cases ordered from most frequent to less frequent */
  501.    switch (CC.Depth.Func) {
  502.       case GL_LESS:
  503.          if (CC.Depth.Mask) {
  504.         /* Update Z buffer */
  505. #ifdef SAFE
  506.         for (i=0; i<n; i++) {
  507.            if (mask[i]) {
  508.           zptr = Z_ADDRESS(x[i],y[i]);
  509.           if (z[i] < *zptr) {
  510.              /* pass */
  511.              *zptr = z[i];
  512.           }
  513.           else {
  514.              /* fail */
  515.              mask[i] = 0;
  516.           }
  517.            }
  518.         }
  519. #else
  520.             /* OPTIMIZED: no branches */
  521.             ZADDR_SETUP;
  522.             for (i=0; i<n; i++) {
  523.                GLdepth *zptr;
  524.                GLint p;
  525.                zptr = ZADDR(x[i],y[i]);
  526.                p = (z[i] < *zptr) & mask[i];   /* 0 or 1 */
  527.                p = 0 - p;                      /* 0 or ~0 */
  528.                *zptr = (*zptr & (~p)) | (z[i] & p);
  529.                mask[i] = p;
  530.             }
  531. #endif
  532.      }
  533.      else {
  534.         /* Don't update Z buffer */
  535. #ifdef SAFE
  536.         for (i=0; i<n; i++) {
  537.            if (mask[i]) {
  538.           zptr = Z_ADDRESS(x[i],y[i]);
  539.           if (z[i] < *zptr) {
  540.              /* pass */
  541.           }
  542.           else {
  543.              /* fail */
  544.              mask[i] = 0;
  545.           }
  546.            }
  547.         }
  548. #else
  549.             /* OPTIMIZED: no branches */
  550.             ZADDR_SETUP;
  551.         for (i=0; i<n; i++) {
  552.                GLdepth *zptr = ZADDR(x[i],y[i]);
  553.                mask[i] &= (z[i] < *zptr);
  554.             }
  555. #endif
  556.      }
  557.      break;
  558.       case GL_LEQUAL:
  559.          if (CC.Depth.Mask) {
  560.         /* Update Z buffer */
  561.         for (i=0; i<n; i++) {
  562.            if (mask[i]) {
  563.           zptr = Z_ADDRESS(x[i],y[i]);
  564.           if (z[i] <= *zptr) {
  565.              /* pass */
  566.              *zptr = z[i];
  567.           }
  568.           else {
  569.              /* fail */
  570.              mask[i] = 0;
  571.           }
  572.            }
  573.         }
  574.      }
  575.      else {
  576.         /* Don't update Z buffer */
  577.         for (i=0; i<n; i++) {
  578.            if (mask[i]) {
  579.           zptr = Z_ADDRESS(x[i],y[i]);
  580.           if (z[i] <= *zptr) {
  581.              /* pass */
  582.           }
  583.           else {
  584.              /* fail */
  585.              mask[i] = 0;
  586.           }
  587.            }
  588.         }
  589.      }
  590.      break;
  591.       case GL_GEQUAL:
  592.          if (CC.Depth.Mask) {
  593.         /* Update Z buffer */
  594.         for (i=0; i<n; i++) {
  595.            if (mask[i]) {
  596.           zptr = Z_ADDRESS(x[i],y[i]);
  597.           if (z[i] >= *zptr) {
  598.              /* pass */
  599.              *zptr = z[i];
  600.           }
  601.           else {
  602.              /* fail */
  603.              mask[i] = 0;
  604.           }
  605.            }
  606.         }
  607.      }
  608.      else {
  609.         /* Don't update Z buffer */
  610.         for (i=0; i<n; i++) {
  611.            if (mask[i]) {
  612.           zptr = Z_ADDRESS(x[i],y[i]);
  613.           if (z[i] >= *zptr) {
  614.              /* pass */
  615.           }
  616.           else {
  617.              /* fail */
  618.              mask[i] = 0;
  619.           }
  620.            }
  621.         }
  622.      }
  623.      break;
  624.       case GL_GREATER:
  625.          if (CC.Depth.Mask) {
  626.         /* Update Z buffer */
  627.         for (i=0; i<n; i++) {
  628.            if (mask[i]) {
  629.           zptr = Z_ADDRESS(x[i],y[i]);
  630.           if (z[i] > *zptr) {
  631.              /* pass */
  632.              *zptr = z[i];
  633.           }
  634.           else {
  635.              /* fail */
  636.              mask[i] = 0;
  637.           }
  638.            }
  639.         }
  640.      }
  641.      else {
  642.         /* Don't update Z buffer */
  643.         for (i=0; i<n; i++) {
  644.            if (mask[i]) {
  645.           zptr = Z_ADDRESS(x[i],y[i]);
  646.           if (z[i] > *zptr) {
  647.              /* pass */
  648.           }
  649.           else {
  650.              /* fail */
  651.              mask[i] = 0;
  652.           }
  653.            }
  654.         }
  655.      }
  656.      break;
  657.       case GL_NOTEQUAL:
  658.          if (CC.Depth.Mask) {
  659.         /* Update Z buffer */
  660.         for (i=0; i<n; i++) {
  661.            if (mask[i]) {
  662.           zptr = Z_ADDRESS(x[i],y[i]);
  663.           if (z[i] != *zptr) {
  664.              /* pass */
  665.              *zptr = z[i];
  666.           }
  667.           else {
  668.              /* fail */
  669.              mask[i] = 0;
  670.           }
  671.            }
  672.         }
  673.      }
  674.      else {
  675.         /* Don't update Z buffer */
  676.         for (i=0; i<n; i++) {
  677.            if (mask[i]) {
  678.           zptr = Z_ADDRESS(x[i],y[i]);
  679.           if (z[i] != *zptr) {
  680.              /* pass */
  681.           }
  682.           else {
  683.              /* fail */
  684.              mask[i] = 0;
  685.           }
  686.            }
  687.         }
  688.      }
  689.      break;
  690.       case GL_EQUAL:
  691.          if (CC.Depth.Mask) {
  692.         /* Update Z buffer */
  693.         for (i=0; i<n; i++) {
  694.            if (mask[i]) {
  695.           zptr = Z_ADDRESS(x[i],y[i]);
  696.           if (z[i] == *zptr) {
  697.              /* pass */
  698.              *zptr = z[i];
  699.           }
  700.           else {
  701.              /* fail */
  702.              mask[i] = 0;
  703.           }
  704.            }
  705.         }
  706.      }
  707.      else {
  708.         /* Don't update Z buffer */
  709.         for (i=0; i<n; i++) {
  710.            if (mask[i]) {
  711.           zptr = Z_ADDRESS(x[i],y[i]);
  712.           if (z[i] == *zptr) {
  713.              /* pass */
  714.           }
  715.           else {
  716.              /* fail */
  717.              mask[i] = 0;
  718.           }
  719.            }
  720.         }
  721.      }
  722.      break;
  723.       case GL_ALWAYS:
  724.      if (CC.Depth.Mask) {
  725.         /* Update Z buffer */
  726. #ifdef SAFE
  727.         for (i=0; i<n; i++) {
  728.            if (mask[i]) {
  729.           zptr = Z_ADDRESS(x[i],y[i]);
  730.           *zptr = z[i];
  731.            }
  732.         }
  733. #else
  734.             /* OPTIMIZED: no branches */
  735.             ZADDR_SETUP;
  736.         for (i=0; i<n; i++) {
  737.                GLdepth *zptr = ZADDR(x[i],y[i]);
  738.                GLint p = 0 - mask[i];   /* 0 or ~0 */
  739.                *zptr = (*zptr & ~p) | (z[i] & p);
  740.         }
  741. #endif
  742.      }
  743.      else {
  744.         /* Don't update Z buffer or mask */
  745.      }
  746.      break;
  747.       case GL_NEVER:
  748.      /* depth test never passes */
  749.      for (i=0;i<n;i++) {
  750.         mask[i] = 0;
  751.      }
  752.      break;
  753.    } /*switch*/
  754. }
  755.  
  756.  
  757.  
  758.  
  759. /*
  760.  * Return a span of depth values from the depth buffer as floats in [0,1].
  761.  * This function is only called through DD.read_depth_span_float()
  762.  * Input:  n - how many pixels
  763.  *         x,y - location of first pixel
  764.  * Output:  depth - the array of depth values
  765.  */
  766. void gl_read_depth_span_float( GLuint n, GLint x, GLint y, GLfloat depth[] )
  767. {
  768.    GLdepth *zptr;
  769.    GLfloat scale;
  770.    GLuint i;
  771.  
  772.    scale = 1.0F / DEPTH_SCALE;
  773.  
  774.    if (CC.DepthBuffer) {
  775.       zptr = Z_ADDRESS( x, y );
  776.       for (i=0;i<n;i++) {
  777.      depth[i] = (GLfloat) zptr[i] * scale;
  778.       }
  779.    }
  780.    else {
  781.       for (i=0;i<n;i++) {
  782.      depth[i] = 0.0F;
  783.       }
  784.    }
  785. }
  786.  
  787.  
  788. /*
  789.  * Return a span of depth values from the depth buffer as integers in
  790.  * [0,MAX_DEPTH].
  791.  * This function is only called through DD.read_depth_span_int()
  792.  * Input:  n - how many pixels
  793.  *         x,y - location of first pixel
  794.  * Output:  depth - the array of depth values
  795.  */
  796. void gl_read_depth_span_int( GLuint n, GLint x, GLint y, GLdepth depth[] )
  797. {
  798.    if (CC.DepthBuffer) {
  799.       GLdepth *zptr = Z_ADDRESS( x, y );
  800.       MEMCPY( depth, zptr, n * sizeof(GLdepth) );
  801.    }
  802.    else {
  803.       GLuint i;
  804.       for (i=0;i<n;i++) {
  805.      depth[i] = 0.0;
  806.       }
  807.    }
  808. }
  809.  
  810.  
  811.  
  812. /*
  813.  * Allocate a new depth buffer.  If there's already a depth buffer allocated
  814.  * it will be free()'d.  The new depth buffer will be uniniitalized.
  815.  * This function is only called through DD.alloc_depth_buffer.
  816.  */
  817. void gl_alloc_depth_buffer( void )
  818. {
  819.    /* deallocate current depth buffer if present */
  820.    if (CC.DepthBuffer) {
  821.       free(CC.DepthBuffer);
  822.       CC.DepthBuffer = NULL;
  823.    }
  824.  
  825.    /* allocate new depth buffer */
  826.    CC.DepthBuffer = (GLdepth *)
  827.         malloc( CC.BufferWidth * CC.BufferHeight * sizeof(GLdepth) );
  828.    if (!CC.DepthBuffer) {
  829.       /* out of memory */
  830.       CC.Depth.Test = GL_FALSE;
  831.       gl_error( GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
  832.    }
  833. }
  834.  
  835.  
  836.  
  837.  
  838. /*
  839.  * Clear the depth buffer.  If the depth buffer doesn't exist yet we'll
  840.  * allocate it now.
  841.  * This function is only called through DD.clear_depth_buffer.
  842.  */
  843. void gl_clear_depth_buffer( void )
  844. {
  845.    /* The loops in this function have been written so the IRIX 5.3
  846.     * C compiler can unroll them.  Hopefully other compilers can too!
  847.     */
  848.  
  849.    if (!CC.DepthBuffer) {
  850.       gl_alloc_depth_buffer();
  851.    }
  852.  
  853.    if (CC.DepthBuffer) {
  854.       GLdepth clear_value = (GLdepth) (CC.Depth.Clear * DEPTH_SCALE);
  855.  
  856.       if (CC.Scissor.Enabled) {
  857.      /* only clear scissor region */
  858.      GLint y;
  859.      for (y=CC.Scissor.Ymin; y<=CC.Scissor.Ymax; y++) {
  860.             GLdepth *d = Z_ADDRESS( CC.Scissor.Xmin, y );
  861.             GLint n = CC.Scissor.Xmax - CC.Scissor.Xmin + 1;
  862.             do {
  863.                *d++ = clear_value;
  864.                n--;
  865.             } while (n);
  866.      }
  867.       }
  868.       else {
  869.      /* clear whole buffer */
  870.      if (sizeof(GLdepth)==2 && (clear_value&0xff)==(clear_value>>8)) {
  871.             /* lower and upper bytes of clear_value are same, use MEMSET */
  872.         MEMSET( CC.DepthBuffer, clear_value&0xff,
  873.                     2*CC.BufferWidth*CC.BufferHeight);
  874.      }
  875.      else {
  876.         GLdepth *d = CC.DepthBuffer;
  877.         GLint n = CC.BufferWidth * CC.BufferHeight;
  878.         while (n>=16) {
  879.            d[0] = clear_value;    d[1] = clear_value;
  880.            d[2] = clear_value;    d[3] = clear_value;
  881.            d[4] = clear_value;    d[5] = clear_value;
  882.            d[6] = clear_value;    d[7] = clear_value;
  883.            d[8] = clear_value;    d[9] = clear_value;
  884.            d[10] = clear_value;   d[11] = clear_value;
  885.            d[12] = clear_value;   d[13] = clear_value;
  886.            d[14] = clear_value;   d[15] = clear_value;
  887.            d += 16;
  888.            n -= 16;
  889.         }
  890.         while (n>0) {
  891.            *d++ = clear_value;
  892.            n--;
  893.         }
  894.      }
  895.       }
  896.    }
  897. }
  898.  
  899.  
  900.  
  901.