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

  1. /* $Id: span.c,v 1.31 1996/04/25 20:41:06 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: span.c,v $
  26.  * Revision 1.31  1996/04/25  20:41:06  brianp
  27.  * replaced gl_depth_test_span() with DD.depth_test_span()
  28.  *
  29.  * Revision 1.30  1996/03/22  20:54:47  brianp
  30.  * replaced CC.ClipSpans with WINCLIP_BIT RasterMask flag
  31.  *
  32.  * Revision 1.29  1996/02/19  21:50:00  brianp
  33.  * added support for software alpha buffering
  34.  *
  35.  * Revision 1.28  1996/02/06  03:23:54  brianp
  36.  * removed gamma correction code
  37.  *
  38.  * Revision 1.27  1996/01/22  15:33:53  brianp
  39.  * use new CC.MutablePixels variable instead of CC.MutableColors
  40.  *
  41.  * Revision 1.26  1996/01/09  19:51:57  brianp
  42.  * fixed a bug in clip_span()
  43.  *
  44.  * Revision 1.25  1995/12/30  01:01:05  brianp
  45.  * gl_write_monocolor_span now takes integer color, not floating point
  46.  *
  47.  * Revision 1.24  1995/12/18  17:27:22  brianp
  48.  * use new GLdepth datatype
  49.  *
  50.  * Revision 1.23  1995/11/30  00:19:52  brianp
  51.  * make copy of span colors if they may be modified and reused
  52.  *
  53.  * Revision 1.22  1995/10/19  15:49:30  brianp
  54.  * added gamma support
  55.  *
  56.  * Revision 1.21  1995/10/13  22:41:16  brianp
  57.  * removed dithering code, added color/index masking code
  58.  *
  59.  * Revision 1.20  1995/09/18  14:21:29  brianp
  60.  * use NULL mask if writing all pixels in a color span
  61.  *
  62.  * Revision 1.19  1995/08/31  21:33:29  brianp
  63.  * use *DD.read_*_span instead of dd_read_*_span
  64.  *
  65.  * Revision 1.18  1995/07/26  15:03:48  brianp
  66.  * replaced some literals with variables for SunOS 4.x per Asif Khan
  67.  *
  68.  * Revision 1.17  1995/07/24  18:58:10  brianp
  69.  * added CC.ClipSpans logic
  70.  *
  71.  * Revision 1.16  1995/06/12  15:42:53  brianp
  72.  * changed color arrays to GLubyte
  73.  *
  74.  * Revision 1.15  1995/05/31  14:57:36  brianp
  75.  * added gl_read_index_span() and gl_read_color_span()
  76.  *
  77.  * Revision 1.14  1995/05/22  21:02:41  brianp
  78.  * Release 1.2
  79.  *
  80.  * Revision 1.13  1995/05/17  13:52:37  brianp
  81.  * implemented glIndexMask(0) and glColorMask(0,0,0,0)
  82.  *
  83.  * Revision 1.12  1995/05/17  13:17:22  brianp
  84.  * changed default CC.Mode value to allow use of real OpenGL headers
  85.  * removed need for CC.MajorMode variable
  86.  *
  87.  * Revision 1.11  1995/05/12  16:28:09  brianp
  88.  * renamed texture functions
  89.  * added clipping for glDrawPixels
  90.  *
  91.  * Revision 1.10  1995/04/11  14:03:27  brianp
  92.  * changed (*CC.write...) to (*DD.write...)
  93.  *
  94.  * Revision 1.9  1995/03/30  21:06:50  brianp
  95.  * updated to use pointers to CC.write_* functions
  96.  *
  97.  * Revision 1.8  1995/03/27  20:32:17  brianp
  98.  * new Texture.Enabled scheme
  99.  *
  100.  * Revision 1.7  1995/03/08  15:10:02  brianp
  101.  * support for dd_logicop
  102.  *
  103.  * Revision 1.6  1995/03/07  19:02:32  brianp
  104.  * updated for new logic blend function names
  105.  *
  106.  * Revision 1.5  1995/03/07  14:21:14  brianp
  107.  * updated for new XSetForeground/GC scheme
  108.  *
  109.  * Revision 1.4  1995/03/04  19:29:44  brianp
  110.  * 1.1 beta revision
  111.  *
  112.  * Revision 1.3  1995/03/01  17:44:31  brianp
  113.  * added stenciling for PB
  114.  *
  115.  * Revision 1.2  1995/02/27  22:49:03  brianp
  116.  * modified for PB
  117.  *
  118.  * Revision 1.1  1995/02/24  14:28:31  brianp
  119.  * Initial revision
  120.  *
  121.  */
  122.  
  123.  
  124. /*
  125.  * pixel span rasterization:
  126.  * These functions simulate the rasterization pipeline.
  127.  */
  128.  
  129.  
  130. #include <string.h>
  131. #include "alpha.h"
  132. #include "alphabuf.h"
  133. #include "blend.h"
  134. #include "context.h"
  135. #include "depth.h"
  136. #include "dd.h"
  137. #include "fog.h"
  138. #include "logic.h"
  139. #include "macros.h"
  140. #include "masking.h"
  141. #include "scissor.h"
  142. #include "span.h"
  143. #include "stencil.h"
  144. #include "texture.h"
  145.  
  146.  
  147. #ifndef NULL
  148. #  define NULL 0
  149. #endif
  150.  
  151.  
  152. /*
  153.  * Apply the current polygon stipple pattern to a span of pixels.
  154.  */
  155. static void stipple_polygon_span( GLuint n, GLint x, GLint y, GLubyte mask[] )
  156. {
  157.    register GLuint i, m, stipple, highbit=0x80000000;
  158.  
  159.    stipple = CC.PolygonStipple[y % 32];
  160.    m = highbit >> (GLuint) (x % 32);
  161.  
  162.    for (i=0;i<n;i++) {
  163.       if ((m & stipple)==0) {
  164.      mask[i] = 0;
  165.       }
  166.       m = m >> 1;
  167.       if (m==0) {
  168.      m = 0x80000000;
  169.       }
  170.    }
  171. }
  172.  
  173.  
  174.  
  175. /*
  176.  * Clip a pixel span to the current buffer/window boundaries.
  177.  * Return:  0 = all pixels clipped
  178.  *          1 = at least one pixel is visible
  179.  */
  180. static GLuint clip_span( GLint n, GLint x, GLint y, GLubyte mask[] )
  181. {
  182.    GLint i;
  183.  
  184.    /* Clip to top and bottom */
  185.    if (y<0 || y>=CC.BufferHeight) {
  186.       return 0;
  187.    }
  188.  
  189.    /* Clip to left and right */
  190.    if (x>=0 && x+n<=CC.BufferWidth) {
  191.       /* no clipping needed */
  192.       return 1;
  193.    }
  194.    else if (x+n<=0) {
  195.       /* completely off left side */
  196.       return 0;
  197.    }
  198.    else if (x>=CC.BufferWidth) {
  199.       /* completely off right side */
  200.       return 0;
  201.    }
  202.    else {
  203.       /* clip-test each pixel, this could be done better */
  204.       for (i=0;i<n;i++) {
  205.          if (x+i<0 || x+i>=CC.BufferWidth) {
  206.             mask[i] = 0;
  207.          }
  208.       }
  209.       return 1;
  210.    }
  211. }
  212.  
  213.  
  214.  
  215. /*
  216.  * Write a horizontal span of color index pixels to the frame buffer.
  217.  * Stenciling, Depth-testing, etc. are done as needed.
  218.  * Input:  n - number of pixels in the span
  219.  *         x, y - location of leftmost pixel in the span
  220.  *         z - array of [n] z-values
  221.  *         index - array of [n] color indexes
  222.  *         primitive - either GL_POINT, GL_LINE, GL_POLYGON, or GL_BITMAP
  223.  */
  224. void gl_write_index_span( GLuint n, GLint x, GLint y, GLdepth z[],
  225.               GLuint index[], GLenum primitive )
  226. {
  227.    GLuint i;
  228.    GLubyte mask[MAX_WIDTH];
  229.  
  230.    /* init mask to 1's (all pixels are to be written) */
  231.    for (i=0;i<n;i++)
  232.       mask[i] = 1;
  233.  
  234.    if ((CC.RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
  235.       if (clip_span(n,x,y,mask)==0) {
  236.      return;
  237.       }
  238.    }
  239.  
  240.    /* Per-pixel fog */
  241.    if (CC.Fog.Enabled && (CC.Hint.Fog==GL_NICEST || primitive==GL_BITMAP)) {
  242.       gl_fog_index_pixels( n, z, index );
  243.    }
  244.  
  245.    /* Do the scissor test */
  246.    if (CC.Scissor.Enabled) {
  247.       if (gl_scissor_span( n, x, y, mask )==0) {
  248.      return;
  249.       }
  250.    }
  251.  
  252.    /* Polygon Stippling */
  253.    if (CC.Polygon.StippleFlag && primitive==GL_POLYGON) {
  254.       stipple_polygon_span( n, x, y, mask );
  255.    }
  256.  
  257.    if (CC.Stencil.Enabled) {
  258.       /* first stencil test */
  259.       if (gl_stencil_span( n, x, y, mask )==0) {
  260.      return;
  261.       }
  262.       /* depth buffering w/ stencil */
  263.       gl_depth_stencil_span( n, x, y, z, mask );
  264.    }
  265.    else if (CC.Depth.Test) {
  266.       /* regular depth testing */
  267.       if ((*DD.depth_test_span)( n, x, y, z, mask )==0)  return;
  268.    }
  269.  
  270.    if (CC.Color.IndexMask==0) {
  271.       /* write no pixels */
  272.       return;
  273.    }
  274.  
  275.    /* logic op */
  276.    if (CC.Color.SWLogicOpEnabled) {
  277.       gl_logic_span( n, x, y, index, mask );
  278.    }
  279.  
  280.    if (CC.Color.SWmasking) {
  281.       gl_mask_index_span( n, x, y, index );
  282.    }
  283.  
  284.    /* write pixels */
  285.    (*DD.write_index_span)( n, x, y, index, mask );
  286. }
  287.  
  288.  
  289.  
  290.  
  291. void gl_write_monoindex_span( GLuint n, GLint x, GLint y, GLdepth z[],
  292.                   GLuint index, GLenum primitive )
  293. {
  294.    GLuint i;
  295.    GLubyte mask[MAX_WIDTH];
  296.  
  297.    /* init mask to 1's (all pixels are to be written) */
  298.    for (i=0;i<n;i++)
  299.       mask[i] = 1;
  300.  
  301.    if ((CC.RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
  302.       if (clip_span(n,x,y,mask)==0) {
  303.      return;
  304.       }
  305.    }
  306.  
  307.    /* Do the scissor test */
  308.    if (CC.Scissor.Enabled) {
  309.       if (gl_scissor_span( n, x, y, mask )==0) {
  310.      return;
  311.       }
  312.    }
  313.  
  314.    /* Polygon Stippling */
  315.    if (CC.Polygon.StippleFlag && primitive==GL_POLYGON) {
  316.       stipple_polygon_span( n, x, y, mask );
  317.    }
  318.  
  319.    if (CC.Stencil.Enabled) {
  320.       /* first stencil test */
  321.       if (gl_stencil_span( n, x, y, mask )==0) {
  322.      return;
  323.       }
  324.       /* depth buffering w/ stencil */
  325.       gl_depth_stencil_span( n, x, y, z, mask );
  326.    }
  327.    else if (CC.Depth.Test) {
  328.       /* regular depth testing */
  329.       if ((*DD.depth_test_span)( n, x, y, z, mask )==0)  return;
  330.    }
  331.  
  332.    if (CC.Color.IndexMask==0) {
  333.       /* write no pixels */
  334.       return;
  335.    }
  336.  
  337.    if ((CC.Fog.Enabled && (CC.Hint.Fog==GL_NICEST || primitive==GL_BITMAP))
  338.         || CC.Color.SWLogicOpEnabled || CC.Color.SWmasking) {
  339.       GLuint ispan[MAX_WIDTH];
  340.       for (i=0;i<n;i++) {
  341.      ispan[i] = index;
  342.       }
  343.  
  344.       if (CC.Fog.Enabled && (CC.Hint.Fog==GL_NICEST || primitive==GL_BITMAP)) {
  345.      gl_fog_index_pixels( n, z, ispan );
  346.       }
  347.  
  348.       if (CC.Color.SWLogicOpEnabled) {
  349.      gl_logic_span( n, x, y, ispan, mask );
  350.       }
  351.  
  352.       if (CC.Color.SWmasking) {
  353.          gl_mask_index_span( n, x, y, ispan );
  354.       }
  355.  
  356.       (*DD.write_index_span)( n, x, y, ispan, mask );
  357.    }
  358.    else {
  359.       (*DD.write_monoindex_span)( n, x, y, mask );
  360.    }
  361. }
  362.  
  363.  
  364.  
  365. void gl_write_color_span( GLuint n, GLint x, GLint y, GLdepth z[],
  366.               GLubyte r[], GLubyte g[],
  367.               GLubyte b[], GLubyte a[],
  368.               GLenum primitive )
  369. {
  370.    GLuint i;
  371.    GLubyte mask[MAX_WIDTH];
  372.    GLboolean write_all = GL_TRUE;
  373.    GLubyte rtmp[MAX_WIDTH], gtmp[MAX_WIDTH], btmp[MAX_WIDTH], atmp[MAX_WIDTH];
  374.    GLubyte *red, *green, *blue, *alpha;
  375.  
  376.    /* init mask to 1's (all pixels are to be written) */
  377.    for (i=0;i<n;i++)
  378.       mask[i] = 1;
  379.  
  380.    if ((CC.RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
  381.       if (clip_span(n,x,y,mask)==0) {
  382.      return;
  383.       }
  384.       write_all = GL_FALSE;
  385.    }
  386.  
  387.    if (primitive==GL_BITMAP && CC.MutablePixels) {
  388.       /* must make a copy of the colors since they may be modified */
  389.       MEMCPY( rtmp, r, n * sizeof(GLubyte) );
  390.       MEMCPY( gtmp, g, n * sizeof(GLubyte) );
  391.       MEMCPY( btmp, b, n * sizeof(GLubyte) );
  392.       MEMCPY( atmp, a, n * sizeof(GLubyte) );
  393.       red = rtmp;
  394.       green = gtmp;
  395.       blue = btmp;
  396.       alpha = atmp;
  397.    }
  398.    else {
  399.       red   = r;
  400.       green = g;
  401.       blue  = b;
  402.       alpha = a;
  403.    }
  404.  
  405.    /* Per-pixel fog */
  406.    if (CC.Fog.Enabled && (CC.Hint.Fog==GL_NICEST || primitive==GL_BITMAP)) {
  407.       gl_fog_color_pixels( n, z, red, green, blue, alpha );
  408.    }
  409.  
  410.    /* Do the scissor test */
  411.    if (CC.Scissor.Enabled) {
  412.       if (gl_scissor_span( n, x, y, mask )==0) {
  413.      return;
  414.       }
  415.       write_all = GL_FALSE;
  416.    }
  417.  
  418.    /* Polygon Stippling */
  419.    if (CC.Polygon.StippleFlag && primitive==GL_POLYGON) {
  420.       stipple_polygon_span( n, x, y, mask );
  421.       write_all = GL_FALSE;
  422.    }
  423.  
  424.    /* Do the alpha test */
  425.    if (CC.Color.AlphaEnabled) {
  426.       if (gl_alpha_test( n, alpha, mask )==0) {
  427.      return;
  428.       }
  429.       write_all = GL_FALSE;
  430.    }
  431.  
  432.    if (CC.Stencil.Enabled) {
  433.       /* first stencil test */
  434.       if (gl_stencil_span( n, x, y, mask )==0) {
  435.      return;
  436.       }
  437.       /* depth buffering w/ stencil */
  438.       gl_depth_stencil_span( n, x, y, z, mask );
  439.       write_all = GL_FALSE;
  440.    }
  441.    else if (CC.Depth.Test) {
  442.       /* regular depth testing */
  443.       GLuint m = (*DD.depth_test_span)( n, x, y, z, mask );
  444.       if (m==0) {
  445.          return;
  446.       }
  447.       if (m<n) {
  448.          write_all = GL_FALSE;
  449.       }
  450.    }
  451.  
  452.    if (CC.Color.ColorMask==0) {
  453.       /* write no pixels */
  454.       return;
  455.    }
  456.  
  457.    /* blending */
  458.    if (CC.Color.BlendEnabled) {
  459.       gl_blend_span( n, x, y, red, green, blue, alpha, mask );
  460.    }
  461.  
  462.    /* Color component masking */
  463.    if (CC.Color.SWmasking) {
  464.       gl_mask_color_span( n, x, y, red, green, blue, alpha );
  465.    }
  466.  
  467.    /* write pixels */
  468.    (*DD.write_color_span)( n, x, y, red, green, blue, alpha,
  469.                            write_all ? NULL : mask );
  470.  
  471.    if (CC.RasterMask & ALPHABUF_BIT) {
  472.       gl_write_alpha_span( n, x, y, alpha, write_all ? NULL : mask );
  473.    }
  474. }
  475.  
  476.  
  477.  
  478. /*
  479.  * Write a horizontal span of color pixels to the frame buffer.
  480.  * The color is initially constant for the whole span.
  481.  * Alpha-testing, stenciling, depth-testing, and blending are done as needed.
  482.  * Input:  n - number of pixels in the span
  483.  *         x, y - location of leftmost pixel in the span
  484.  *         z - array of [n] z-values
  485.  *         r, g, b, a - the color of the pixels
  486.  *         primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
  487.  */
  488. void gl_write_monocolor_span( GLuint n, GLint x, GLint y, GLdepth z[],
  489.                   GLint r, GLint g, GLint b, GLint a,
  490.                               GLenum primitive )
  491. {
  492.    GLuint i;
  493.    GLubyte mask[MAX_WIDTH];
  494.    GLboolean write_all = GL_TRUE;
  495.  
  496.    /* init mask to 1's (all pixels are to be written) */
  497.    for (i=0;i<n;i++)
  498.       mask[i] = 1;
  499.  
  500.    if ((CC.RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
  501.       if (clip_span(n,x,y,mask)==0) {
  502.      return;
  503.       }
  504.       write_all = GL_FALSE;
  505.    }
  506.  
  507.    /* Do the scissor test */
  508.    if (CC.Scissor.Enabled) {
  509.       if (gl_scissor_span( n, x, y, mask )==0) {
  510.      return;
  511.       }
  512.       write_all = GL_FALSE;
  513.    }
  514.  
  515.    /* Polygon Stippling */
  516.    if (CC.Polygon.StippleFlag && primitive==GL_POLYGON) {
  517.       stipple_polygon_span( n, x, y, mask );
  518.       write_all = GL_FALSE;
  519.    }
  520.  
  521.    /* Do the alpha test */
  522.    if (CC.Color.AlphaEnabled) {
  523.       GLubyte alpha[MAX_WIDTH];
  524.       for (i=0;i<n;i++) {
  525.          alpha[i] = a;
  526.       }
  527.       if (gl_alpha_test( n, alpha, mask )==0) {
  528.      return;
  529.       }
  530.       write_all = GL_FALSE;
  531.    }
  532.  
  533.    if (CC.Stencil.Enabled) {
  534.       /* first stencil test */
  535.       if (gl_stencil_span( n, x, y, mask )==0) {
  536.      return;
  537.       }
  538.       /* depth buffering w/ stencil */
  539.       gl_depth_stencil_span( n, x, y, z, mask );
  540.       write_all = GL_FALSE;
  541.    }
  542.    else if (CC.Depth.Test) {
  543.       /* regular depth testing */
  544.       GLuint m = (*DD.depth_test_span)( n, x, y, z, mask );
  545.       if (m==0) {
  546.          return;
  547.       }
  548.       if (m<n) {
  549.          write_all = GL_FALSE;
  550.       }
  551.    }
  552.  
  553.    if (CC.Color.ColorMask==0) {
  554.       /* write no pixels */
  555.       return;
  556.    }
  557.  
  558.    if (CC.Color.BlendEnabled || CC.Color.SWmasking) {
  559.       /* assign same color to each pixel */
  560.       GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  561.       GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  562.       for (i=0;i<n;i++) {
  563.      if (mask[i]) {
  564.         red[i]   = r;
  565.         green[i] = g;
  566.         blue[i]  = b;
  567.         alpha[i] = a;
  568.      }
  569.       }
  570.  
  571.       if (CC.Color.BlendEnabled) {
  572.          gl_blend_span( n, x, y, red, green, blue, alpha, mask );
  573.       }
  574.  
  575.       /* Color component masking */
  576.       if (CC.Color.SWmasking) {
  577.          gl_mask_color_span( n, x, y, red, green, blue, alpha );
  578.       }
  579.  
  580.       /* write pixels */
  581.       (*DD.write_color_span)( n, x, y, red, green, blue, alpha,
  582.                               write_all ? NULL : mask );
  583.       if (CC.RasterMask & ALPHABUF_BIT) {
  584.          gl_write_alpha_span( n, x, y, alpha, write_all ? NULL : mask );
  585.       }
  586.    }
  587.    else {
  588.       (*DD.write_monocolor_span)( n, x, y, mask );
  589.       if (CC.RasterMask & ALPHABUF_BIT) {
  590.          gl_write_mono_alpha_span( n, x, y, a, write_all ? NULL : mask );
  591.       }
  592.    }
  593. }
  594.  
  595.  
  596.  
  597. /*
  598.  * Write a horizontal span of textured pixels to the frame buffer.
  599.  * The color of each pixel is different.
  600.  * Alpha-testing, stenciling, depth-testing, and blending are done
  601.  * as needed.
  602.  * Input:  n - number of pixels in the span
  603.  *         x, y - location of leftmost pixel in the span
  604.  *         z - array of [n] z-values
  605.  *         s, t - array of (s,t) texture coordinates for each pixel
  606.  *         red, green, blue, alpha - array of [n] color components
  607.  *         primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
  608.  */
  609. void gl_write_texture_span( GLuint n, GLint x, GLint y, GLdepth z[],
  610.                 GLfloat s[], GLfloat t[],
  611.                 GLubyte r[], GLubyte g[],
  612.                 GLubyte b[], GLubyte a[],
  613.                 GLenum primitive )
  614. {
  615.    GLuint i;
  616.    GLubyte mask[MAX_WIDTH];
  617.    GLboolean write_all = GL_TRUE;
  618.    GLubyte rtmp[MAX_WIDTH], gtmp[MAX_WIDTH], btmp[MAX_WIDTH], atmp[MAX_WIDTH];
  619.    GLubyte *red, *green, *blue, *alpha;
  620.  
  621.    /* init mask to 1's (all pixels are to be written) */
  622.    for (i=0;i<n;i++)
  623.       mask[i] = 1;
  624.  
  625.    if ((CC.RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) {
  626.       if (clip_span(n,x,y,mask)==0) {
  627.      return;
  628.       }
  629.       write_all = GL_FALSE;
  630.    }
  631.  
  632.  
  633.    if (primitive==GL_BITMAP) {
  634.       /* must make a copy of the colors since they may be modified */
  635.       MEMCPY( rtmp, r, n * sizeof(GLubyte) );
  636.       MEMCPY( gtmp, g, n * sizeof(GLubyte) );
  637.       MEMCPY( btmp, b, n * sizeof(GLubyte) );
  638.       MEMCPY( atmp, a, n * sizeof(GLubyte) );
  639.       red = rtmp;
  640.       green = gtmp;
  641.       blue = btmp;
  642.       alpha = atmp;
  643.    }
  644.    else {
  645.       red   = r;
  646.       green = g;
  647.       blue  = b;
  648.       alpha = a;
  649.    }
  650.  
  651.    /* Texture */
  652.    if (CC.Texture.Enabled & 2) {
  653.       gl_texture_pixels_2d( n, s, t, red, green, blue, alpha );
  654.    }
  655.    else if (CC.Texture.Enabled & 1) {
  656.       gl_texture_pixels_1d( n, s, red, green, blue, alpha );
  657.    }
  658.  
  659.  
  660.    /* Per-pixel fog */
  661.    if (CC.Fog.Enabled && (CC.Hint.Fog==GL_NICEST || primitive==GL_BITMAP)) {
  662.       gl_fog_color_pixels( n, z, red, green, blue, alpha );
  663.    }
  664.  
  665.    /* Do the scissor test */
  666.    if (CC.Scissor.Enabled) {
  667.       if (gl_scissor_span( n, x, y, mask )==0) {
  668.      return;
  669.       }
  670.       write_all = GL_FALSE;
  671.    }
  672.  
  673.    /* Polygon Stippling */
  674.    if (CC.Polygon.StippleFlag && primitive==GL_POLYGON) {
  675.       stipple_polygon_span( n, x, y, mask );
  676.       write_all = GL_FALSE;
  677.    }
  678.  
  679.    /* Do the alpha test */
  680.    if (CC.Color.AlphaEnabled) {
  681.       if (gl_alpha_test( n, alpha, mask )==0) {
  682.      return;
  683.       }
  684.       write_all = GL_FALSE;
  685.    }
  686.  
  687.    if (CC.Stencil.Enabled) {
  688.       /* first stencil test */
  689.       if (gl_stencil_span( n, x, y, mask )==0) {
  690.      return;
  691.       }
  692.       /* depth buffering w/ stencil */
  693.       gl_depth_stencil_span( n, x, y, z, mask );
  694.       write_all = GL_FALSE;
  695.    }
  696.    else if (CC.Depth.Test) {
  697.       /* regular depth testing */
  698.       GLuint m = (*DD.depth_test_span)( n, x, y, z, mask );
  699.       if (m==0) {
  700.          return;
  701.       }
  702.       if (m<n) {
  703.          write_all = GL_FALSE;
  704.       }
  705.    }
  706.  
  707.    if (CC.Color.ColorMask==0) {
  708.       /* write no pixels */
  709.       return;
  710.    }
  711.  
  712.    /* blending */
  713.    if (CC.Color.BlendEnabled) {
  714.       gl_blend_span( n, x, y, red, green, blue, alpha, mask );
  715.    }
  716.  
  717.    if (CC.Color.SWmasking) {
  718.       gl_mask_color_span( n, x, y, red, green, blue, alpha );
  719.    }
  720.  
  721.    /* write pixels */
  722.    (*DD.write_color_span)( n, x, y, red, green, blue, alpha,
  723.                            write_all ? NULL : mask );
  724.    if (CC.RasterMask & ALPHABUF_BIT) {
  725.       gl_write_alpha_span( n, x, y, alpha, write_all ? NULL : mask );
  726.    }
  727. }
  728.  
  729.  
  730.  
  731. /*
  732.  * Read RGBA pixels from frame buffer.  Clipping will be done to prevent
  733.  * reading ouside the buffer's boundaries.
  734.  */
  735. void gl_read_color_span( GLuint n, GLint x, GLint y,
  736.              GLubyte red[], GLubyte green[],
  737.              GLubyte blue[], GLubyte alpha[] )
  738. {
  739.    register GLuint i;
  740.  
  741.    if (y<0 || y>=CC.BufferHeight || x>=CC.BufferWidth) {
  742.       /* completely above, below, or right */
  743.       for (i=0;i<n;i++) {
  744.      red[i] = green[i] = blue[i] = alpha[i] = 0;
  745.       }
  746.    }
  747.    else {
  748.       if (x>=0 && x+n<=CC.BufferWidth) {
  749.      /* OK */
  750.      (*DD.read_color_span)( n, x, y, red, green, blue, alpha );
  751.          if (CC.RasterMask & ALPHABUF_BIT) {
  752.             gl_read_alpha_span( n, x, y, alpha );
  753.          }
  754.       }
  755.       else {
  756.      i = 0;
  757.      if (x<0) {
  758.         while (x<0 && n>0) {
  759.            red[i] = green[i] =  blue[i] = alpha[i] = 0;
  760.            x++;
  761.            n--;
  762.            i++;
  763.         }
  764.      }
  765.      n = MIN2( n, CC.BufferWidth - x );
  766.      (*DD.read_color_span)( n, x, y, red+i, green+i, blue+i, alpha+i );
  767.          if (CC.RasterMask & ALPHABUF_BIT) {
  768.             gl_read_alpha_span( n, x, y, alpha+i );
  769.          }
  770.       }
  771.    }
  772. }
  773.  
  774.  
  775.  
  776.  
  777. /*
  778.  * Read CI pixels from frame buffer.  Clipping will be done to prevent
  779.  * reading ouside the buffer's boundaries.
  780.  */
  781. void gl_read_index_span( GLuint n, GLint x, GLint y, GLuint indx[] )
  782. {
  783.    register GLuint i;
  784.  
  785.    if (y<0 || y>=CC.BufferHeight || x>=CC.BufferWidth) {
  786.       /* completely above, below, or right */
  787.       for (i=0;i<n;i++) {
  788.      indx[i] = 0;
  789.       }
  790.    }
  791.    else {
  792.       if (x>=0 && x+n<=CC.BufferWidth) {
  793.      /* OK */
  794.      (*DD.read_index_span)( n, x, y, indx );
  795.       }
  796.       else {
  797.      i = 0;
  798.      if (x<0) {
  799.         while (x<0 && n>0) {
  800.            indx[i] = 0;
  801.            x++;
  802.            n--;
  803.            i++;
  804.         }
  805.      }
  806.      n = MIN2( n, CC.BufferWidth - x );
  807.      (*DD.read_index_span)( n, x, y, indx+i );
  808.       }
  809.    }
  810. }
  811.  
  812.  
  813.