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

  1. /* $Id: pb.c,v 1.31 1996/04/25 20:40:07 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: pb.c,v $
  26.  * Revision 1.31  1996/04/25  20:40:07  brianp
  27.  * replaced gl_depth_test_pixels() calls with DD.depth_test_pixels
  28.  *
  29.  * Revision 1.30  1996/03/29  15:27:30  brianp
  30.  * RGBA masking and blending were done in the wrong order
  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:31:49  brianp
  39.  * replaced gl_init_pb() with PB_INIT macro
  40.  * removed polygon stippling code (not needed)
  41.  * use CC.MutablePixels instead of PB.mutable
  42.  *
  43.  * Revision 1.26  1995/12/30  00:57:46  brianp
  44.  * use integer colors instead of floating point
  45.  *
  46.  * Revision 1.25  1995/11/09  16:57:05  brianp
  47.  * added some missing PB.count=0 statements per Johan Nouvel
  48.  *
  49.  * Revision 1.24  1995/11/03  22:36:04  brianp
  50.  * fixed fogging bug
  51.  *
  52.  * Revision 1.23  1995/10/30  15:31:14  brianp
  53.  * added mask argument to gl_mask_[color|index]_pixels calls
  54.  *
  55.  * Revision 1.22  1995/10/19  15:47:51  brianp
  56.  * added gamma support
  57.  *
  58.  * Revision 1.21  1995/10/13  22:41:43  brianp
  59.  * removed dithering code, added color/index masking code
  60.  *
  61.  * Revision 1.20  1995/09/27  19:22:22  brianp
  62.  * optimized several loops, replaced some with memset()
  63.  *
  64.  * Revision 1.19  1995/07/26  15:03:48  brianp
  65.  * replaced some literals with variables for SunOS 4.x per Asif Khan
  66.  *
  67.  * Revision 1.18  1995/07/15  14:04:19  brianp
  68.  * enabled texture mapping
  69.  *
  70.  * Revision 1.17  1995/06/20  16:18:53  brianp
  71.  * removed clipflag logic, clip all pixels
  72.  *
  73.  * Revision 1.16  1995/06/12  15:42:14  brianp
  74.  * changed some indentations
  75.  *
  76.  * Revision 1.15  1995/06/05  20:26:51  brianp
  77.  * better PB.clipflag setup
  78.  *
  79.  * Revision 1.14  1995/05/22  21:02:41  brianp
  80.  * Release 1.2
  81.  *
  82.  * Revision 1.13  1995/05/18  14:43:31  brianp
  83.  * implemented glIndexMask(0) and glColorMask(0,0,0,0)
  84.  *
  85.  * Revision 1.12  1995/05/17  13:17:22  brianp
  86.  * changed default CC.Mode value to allow use of real OpenGL headers
  87.  * removed need for CC.MajorMode variable
  88.  *
  89.  * Revision 1.11  1995/05/12  16:26:33  brianp
  90.  * added pixel clipping
  91.  *
  92.  * Revision 1.10  1995/04/11  14:04:40  brianp
  93.  * changed (*CC.write...) to (*DD.write...)
  94.  *
  95.  * Revision 1.9  1995/03/30  21:07:32  brianp
  96.  * updated to use pointers to CC.write_* functions
  97.  *
  98.  * Revision 1.8  1995/03/27  20:32:17  brianp
  99.  * new Texture.Enabled scheme
  100.  *
  101.  * Revision 1.7  1995/03/08  15:10:02  brianp
  102.  * support for dd_logicop
  103.  *
  104.  * Revision 1.6  1995/03/07  19:02:08  brianp
  105.  * added logicop, blending, and alpha test
  106.  *
  107.  * Revision 1.5  1995/03/07  14:21:05  brianp
  108.  * updated for new XSetForeground/GC scheme
  109.  *
  110.  * Revision 1.4  1995/03/04  19:29:44  brianp
  111.  * 1.1 beta revision
  112.  *
  113.  * Revision 1.3  1995/03/01  17:44:22  brianp
  114.  * added stenciling for PB
  115.  *
  116.  * Revision 1.2  1995/02/27  22:48:56  brianp
  117.  * modified for PB
  118.  *
  119.  * Revision 1.1  1995/02/24  17:51:55  brianp
  120.  * Initial revision
  121.  *
  122.  */
  123.  
  124.  
  125. /*
  126.  * Pixel buffer:
  127.  *
  128.  * As fragments are produced (by point, line, and bitmap drawing) they
  129.  * are accumlated in a buffer.  When the buffer is full or has to be
  130.  * flushed (glEnd), we apply all enabled rasterization functions to the
  131.  * pixels and write the results to the display buffer.  The goal is to
  132.  * maximize the number of pixels processed inside loops and to minimize
  133.  * the number of function calls.
  134.  */
  135.  
  136.  
  137.  
  138. #include <string.h>
  139. #include "alpha.h"
  140. #include "alphabuf.h"
  141. #include "blend.h"
  142. #include "context.h"
  143. #include "dd.h"
  144. #include "depth.h"
  145. #include "fog.h"
  146. #include "logic.h"
  147. #include "macros.h"
  148. #include "masking.h"
  149. #include "pb.h"
  150. #include "scissor.h"
  151. #include "stencil.h"
  152. #include "texture.h"
  153.  
  154.  
  155. struct pixel_buffer PB;
  156.  
  157.  
  158.  
  159. /*
  160.  * When the pixel buffer is full, or needs to be flushed, call this
  161.  * function.  All the pixels in the pixel buffer will be subjected
  162.  * to texturing, scissoring, stippling, alpha testing, stenciling,
  163.  * depth testing, blending, and finally written to the frame buffer.
  164.  */
  165. void gl_flush_pb( void )
  166. {
  167.    GLubyte mask[PB_SIZE+4];   /* add 4 for manually unrolled loop, below */
  168.  
  169. #ifdef DEBUG
  170.    printf("Flush: %d\n", PB.count );
  171. #endif
  172.  
  173.    if (PB.count==0)  return;
  174.  
  175.    /* initialize mask array and clip pixels simultaneously */
  176.    {
  177.       GLint w = CC.BufferWidth;
  178.       GLint h = CC.BufferHeight;
  179.       GLuint i = 0;
  180.       /* manually unrolled loop, OK to go past PB.count */
  181.       do {
  182.          mask[i] = (PB.x[i]>=0) & (PB.x[i]<w) & (PB.y[i]>=0) & (PB.y[i]<h);
  183.          i++;
  184.          mask[i] = (PB.x[i]>=0) & (PB.x[i]<w) & (PB.y[i]>=0) & (PB.y[i]<h);
  185.          i++;
  186.          mask[i] = (PB.x[i]>=0) & (PB.x[i]<w) & (PB.y[i]>=0) & (PB.y[i]<h);
  187.          i++;
  188.          mask[i] = (PB.x[i]>=0) & (PB.x[i]<w) & (PB.y[i]>=0) & (PB.y[i]<h);
  189.          i++;
  190.       } while (i<PB.count);
  191.    }
  192.  
  193.    if (CC.RGBAflag) {
  194.       /* RGBA COLOR PIXELS */
  195.  
  196.       if (PB.mono && CC.MutablePixels) {
  197.      /* Copy flat color to all pixels */
  198.          MEMSET( PB.r, PB.color[0], PB.count );
  199.          MEMSET( PB.g, PB.color[1], PB.count );
  200.          MEMSET( PB.b, PB.color[2], PB.count );
  201.          MEMSET( PB.a, PB.color[3], PB.count );
  202.       }
  203.  
  204.       /* If each pixel can be of a different color... */
  205.       if (CC.MutablePixels || !PB.mono) {
  206.  
  207.      if (CC.Texture.Enabled & 2) {
  208.         gl_texture_pixels_2d(PB.count, PB.s, PB.t, PB.r, PB.g, PB.b, PB.a);
  209.      }
  210.      else if (CC.Texture.Enabled & 1) {
  211.         gl_texture_pixels_1d( PB.count, PB.s, PB.r, PB.g, PB.b, PB.a );
  212.      }
  213.  
  214.      if (CC.Fog.Enabled
  215.              && (CC.Hint.Fog==GL_NICEST || PB.primitive==GL_BITMAP)) {
  216.         gl_fog_color_pixels( PB.count, PB.z,
  217.                  PB.r, PB.g, PB.b, PB.a );
  218.      }
  219.  
  220.      if (CC.Scissor.Enabled) {
  221.         if (gl_scissor_pixels( PB.count, PB.x, PB.y, mask )==0) {
  222.            PB.count = 0;
  223.            return;
  224.         }
  225.      }
  226.  
  227.      if (CC.Color.AlphaEnabled) {
  228.         if (gl_alpha_test( PB.count, PB.a, mask )==0) {
  229.            PB.count = 0;
  230.            return;
  231.         }
  232.      }
  233.  
  234.      if (CC.Stencil.Enabled) {
  235.         /* first stencil test */
  236.         if (gl_stencil_pixels( PB.count, PB.x, PB.y, mask )==0) {
  237.            PB.count = 0;
  238.            return;
  239.         }
  240.         /* depth buffering w/ stencil */
  241.         gl_depth_stencil_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  242.      }
  243.      else if (CC.Depth.Test) {
  244.         /* regular depth testing */
  245.         (*DD.depth_test_pixels)( PB.count, PB.x, PB.y, PB.z, mask );
  246.      }
  247.  
  248.      if (CC.Color.ColorMask) {
  249.             if (CC.Color.BlendEnabled) {
  250.                gl_blend_pixels( PB.count, PB.x, PB.y,
  251.                                 PB.r, PB.g, PB.b, PB.a, mask);
  252.             }
  253.  
  254.             if (CC.Color.SWmasking) {
  255.                gl_mask_color_pixels( PB.count, PB.x, PB.y,
  256.                                      PB.r, PB.g, PB.b, PB.a, mask );
  257.             }
  258.  
  259.             /* write pixels */
  260.             (*DD.write_color_pixels)( PB.count, PB.x, PB.y,
  261.                                       PB.r, PB.g, PB.b, PB.a, mask );
  262.             if (CC.RasterMask & ALPHABUF_BIT) {
  263.                gl_write_alpha_pixels( PB.count, PB.x, PB.y, PB.a, mask );
  264.             }
  265.          }
  266.  
  267.       }
  268.       else {
  269.      /* Same color for all pixels */
  270.  
  271.      if (CC.Scissor.Enabled) {
  272.         if (gl_scissor_pixels( PB.count, PB.x, PB.y, mask )==0) {
  273.                PB.count = 0;
  274.            return;
  275.         }
  276.      }
  277.  
  278.      if (CC.Color.AlphaEnabled) {
  279.         if (gl_alpha_test( PB.count, PB.a, mask )==0) {
  280.                PB.count = 0;
  281.            return;
  282.         }
  283.      }
  284.  
  285.      if (CC.Stencil.Enabled) {
  286.         /* first stencil test */
  287.         if (gl_stencil_pixels( PB.count, PB.x, PB.y, mask )==0) {
  288.                PB.count = 0;
  289.            return;
  290.         }
  291.         /* depth buffering w/ stencil */
  292.         gl_depth_stencil_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  293.      }
  294.      else if (CC.Depth.Test) {
  295.         /* regular depth testing */
  296.         (*DD.depth_test_pixels)( PB.count, PB.x, PB.y, PB.z, mask );
  297.      }
  298.  
  299.      if (CC.Color.ColorMask) {
  300.         /* write pixels */
  301.             GLubyte red, green, blue, alpha;
  302.             red   = PB.color[0];
  303.             green = PB.color[1];
  304.             blue  = PB.color[2];
  305.             alpha = PB.color[3];
  306.         (*DD.color)( red, green, blue, alpha );
  307.         (*DD.write_monocolor_pixels)( PB.count, PB.x, PB.y, mask );
  308.             if (CC.RasterMask & ALPHABUF_BIT) {
  309.                gl_write_mono_alpha_pixels( PB.count, PB.x, PB.y, alpha, mask );
  310.             }
  311.      }
  312.       }
  313.    }
  314.    else {
  315.       /* COLOR INDEX PIXELS */
  316.  
  317.       /* If we may be writting pixels with different indexes... */
  318.       if (PB.mono && CC.MutablePixels) {
  319.      /* copy index to all pixels */
  320.          GLuint n = PB.count, indx = PB.index;
  321.          GLuint *pbindex = PB.i;
  322.          do {
  323.         *pbindex++ = indx;
  324.             n--;
  325.      } while (n);
  326.       }
  327.  
  328.       if (CC.MutablePixels || !PB.mono) {
  329.      /* Pixel color index may be modified */
  330.  
  331.      if (CC.Fog.Enabled
  332.              && (CC.Hint.Fog==GL_NICEST || PB.primitive==GL_BITMAP)) {
  333.         gl_fog_index_pixels( PB.count, PB.z, PB.i );
  334.      }
  335.  
  336.      if (CC.Scissor.Enabled) {
  337.         if (gl_scissor_pixels( PB.count, PB.x, PB.y, mask )==0) {
  338.                PB.count = 0;
  339.            return;
  340.         }
  341.      }
  342.  
  343.      if (CC.Stencil.Enabled) {
  344.         /* first stencil test */
  345.         if (gl_stencil_pixels( PB.count, PB.x, PB.y, mask )==0) {
  346.                PB.count = 0;
  347.            return;
  348.         }
  349.         /* depth buffering w/ stencil */
  350.         gl_depth_stencil_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  351.      }
  352.      else if (CC.Depth.Test) {
  353.         /* regular depth testing */
  354.         (*DD.depth_test_pixels)( PB.count, PB.x, PB.y, PB.z, mask );
  355.      }
  356.  
  357.      if (CC.Color.IndexMask) {
  358.         if (CC.Color.SWLogicOpEnabled) {
  359.            gl_logic_pixels( PB.count, PB.x, PB.y, PB.i, mask );
  360.         }
  361.  
  362.             if (CC.Color.SWmasking) {
  363.                gl_mask_index_pixels( PB.count, PB.x, PB.y, PB.i, mask );
  364.             }
  365.  
  366.         /* write pixels */
  367.         (*DD.write_index_pixels)( PB.count, PB.x, PB.y, PB.i, mask );
  368.      }
  369.       }
  370.       else {
  371.      /* Same color index for all pixels */
  372.  
  373.      if (CC.Scissor.Enabled) {
  374.         if (gl_scissor_pixels( PB.count, PB.x, PB.y, mask )==0) {
  375.                PB.count = 0;
  376.            return;
  377.         }
  378.      }
  379.  
  380.      if (CC.Stencil.Enabled) {
  381.         /* first stencil test */
  382.         if (gl_stencil_pixels( PB.count, PB.x, PB.y, mask )==0) {
  383.                PB.count = 0;
  384.            return;
  385.         }
  386.         /* depth buffering w/ stencil */
  387.         gl_depth_stencil_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  388.      }
  389.      else if (CC.Depth.Test) {
  390.         /* regular depth testing */
  391.         (*DD.depth_test_pixels)( PB.count, PB.x, PB.y, PB.z, mask );
  392.      }
  393.  
  394.      if (CC.Color.IndexMask) {
  395.         /* write pixels */
  396.         (*DD.index)( PB.index );
  397.         (*DD.write_monoindex_pixels)( PB.count, PB.x, PB.y, mask );
  398.      }
  399.       }
  400.    }
  401.  
  402.    PB.count = 0;
  403. }
  404.  
  405.