home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / s_buffers.cpp < prev    next >
C/C++ Source or Header  |  2002-11-13  |  9KB  |  289 lines

  1. /* $Id: s_buffers.c,v 1.16 2002/11/13 16:46:19 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  5.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. #include "glheader.h"
  29. #include "colormac.h"
  30. #include "macros.h"
  31. #include "imports.h"
  32.  
  33. #include "s_accum.h"
  34. #include "s_alphabuf.h"
  35. #include "s_context.h"
  36. #include "s_depth.h"
  37. #include "s_masking.h"
  38. #include "s_stencil.h"
  39.  
  40.  
  41.  
  42.  
  43. /*
  44.  * Clear the color buffer when glColorMask or glIndexMask is in effect.
  45.  */
  46. static void
  47. clear_color_buffer_with_masking( GLcontext *ctx )
  48. {
  49.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  50.    const GLint x = ctx->DrawBuffer->_Xmin;
  51.    const GLint y = ctx->DrawBuffer->_Ymin;
  52.    const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
  53.    const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
  54.  
  55.    if (ctx->Visual.rgbMode) {
  56.       /* RGBA mode */
  57.       GLchan clearColor[4];
  58.       GLint i;
  59.       CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]);
  60.       CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]);
  61.       CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]);
  62.       CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]);
  63.       for (i = 0; i < height; i++) {
  64.          GLchan rgba[MAX_WIDTH][4];
  65.          GLint j;
  66.          for (j = 0; j < width; j++) {
  67.             COPY_CHAN4(rgba[j], clearColor);
  68.          }
  69.          _mesa_mask_rgba_array( ctx, width, x, y + i, rgba );
  70.          (*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i,
  71.                                           (CONST GLchan (*)[4]) rgba, NULL );
  72.       }
  73.    }
  74.    else {
  75.       /* Color index mode */
  76.       GLuint span[MAX_WIDTH];
  77.       GLubyte mask[MAX_WIDTH];
  78.       GLint i, j;
  79.       MEMSET( mask, 1, width );
  80.       for (i=0;i<height;i++) {
  81.          for (j=0;j<width;j++) {
  82.             span[j] = ctx->Color.ClearIndex;
  83.          }
  84.          _mesa_mask_index_array( ctx, width, x, y + i, span );
  85.          (*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask );
  86.       }
  87.    }
  88. }
  89.  
  90.  
  91.  
  92. /*
  93.  * Clear a color buffer without index/channel masking.
  94.  */
  95. static void
  96. clear_color_buffer(GLcontext *ctx)
  97. {
  98.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  99.    const GLint x = ctx->DrawBuffer->_Xmin;
  100.    const GLint y = ctx->DrawBuffer->_Ymin;
  101.    const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
  102.    const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
  103.  
  104.    if (ctx->Visual.rgbMode) {
  105.       /* RGBA mode */
  106.       GLchan clearColor[4];
  107.       GLint i;
  108.  
  109.       CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]);
  110.       CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]);
  111.       CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]);
  112.       CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]);
  113.  
  114.       ASSERT(*((GLuint *) &ctx->Color.ColorMask) == 0xffffffff);
  115.       ASSERT(swrast->Driver.WriteRGBASpan);
  116.  
  117.       for (i = 0; i < height; i++) {
  118.          (*swrast->Driver.WriteMonoRGBASpan)( ctx, width, x, y + i,
  119.                                               clearColor, NULL );
  120.       }
  121.    }
  122.    else {
  123.       /* Color index mode */
  124.       GLint i;
  125.       ASSERT((ctx->Color.IndexMask & ((1 << ctx->Visual.indexBits) - 1))
  126.              == (GLuint) ((1 << ctx->Visual.indexBits) - 1));
  127.       ASSERT(swrast->Driver.WriteMonoCISpan);
  128.       for (i = 0; i < height; i++) {
  129.          (*swrast->Driver.WriteMonoCISpan)( ctx, width, x, y + i,
  130.                                             ctx->Color.ClearIndex, NULL);
  131.       }
  132.    }
  133. }
  134.  
  135.  
  136.  
  137. /*
  138.  * Clear the front/back/left/right color buffers.
  139.  * This function is usually only called if we need to clear the
  140.  * buffers with masking.
  141.  */
  142. static void
  143. clear_color_buffers(GLcontext *ctx)
  144. {
  145.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  146.    const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
  147.    GLuint bufferBit;
  148.  
  149.    /* loop over four possible dest color buffers */
  150.    for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
  151.       if (bufferBit & ctx->Color._DrawDestMask) {
  152.          (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
  153.  
  154.          if (colorMask != 0xffffffff) {
  155.             clear_color_buffer_with_masking(ctx);
  156.          }
  157.          else {
  158.             clear_color_buffer(ctx);
  159.          }
  160.       }
  161.    }
  162.  
  163.    /* restore default read/draw buffer */
  164.    _swrast_use_draw_buffer(ctx);
  165. }
  166.  
  167.  
  168.  
  169. void
  170. _swrast_Clear( GLcontext *ctx, GLbitfield mask,
  171.            GLboolean all,
  172.            GLint x, GLint y, GLint width, GLint height )
  173. {
  174.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  175. #ifdef DEBUG
  176.    {
  177.       GLbitfield legalBits = DD_FRONT_LEFT_BIT |
  178.      DD_FRONT_RIGHT_BIT |
  179.      DD_BACK_LEFT_BIT |
  180.      DD_BACK_RIGHT_BIT |
  181.      DD_DEPTH_BIT |
  182.      DD_STENCIL_BIT |
  183.      DD_ACCUM_BIT;
  184.       assert((mask & (~legalBits)) == 0);
  185.    }
  186. #endif
  187.  
  188.    RENDER_START(swrast,ctx);
  189.  
  190.    /* do software clearing here */
  191.    if (mask) {
  192.       if (mask & ctx->Color._DrawDestMask)   clear_color_buffers(ctx);
  193.       if (mask & GL_DEPTH_BUFFER_BIT)    _mesa_clear_depth_buffer(ctx);
  194.       if (mask & GL_ACCUM_BUFFER_BIT)    _mesa_clear_accum_buffer(ctx);
  195.       if (mask & GL_STENCIL_BUFFER_BIT)  _mesa_clear_stencil_buffer(ctx);
  196.    }
  197.  
  198.    /* clear software-based alpha buffer(s) */
  199.    if ( (mask & GL_COLOR_BUFFER_BIT)
  200.     && ctx->DrawBuffer->UseSoftwareAlphaBuffers
  201.     && ctx->Color.ColorMask[ACOMP]) {
  202.       _mesa_clear_alpha_buffers( ctx );
  203.    }
  204.  
  205.    RENDER_FINISH(swrast,ctx);
  206. }
  207.  
  208.  
  209. void
  210. _swrast_alloc_buffers( GLframebuffer *buffer )
  211. {
  212.    /* Reallocate other buffers if needed. */
  213.    if (buffer->UseSoftwareDepthBuffer) {
  214.       _mesa_alloc_depth_buffer( buffer );
  215.    }
  216.    if (buffer->UseSoftwareStencilBuffer) {
  217.       _mesa_alloc_stencil_buffer( buffer );
  218.    }
  219.    if (buffer->UseSoftwareAccumBuffer) {
  220.       _mesa_alloc_accum_buffer( buffer );
  221.    }
  222.    if (buffer->UseSoftwareAlphaBuffers) {
  223.       _mesa_alloc_alpha_buffers( buffer );
  224.    }
  225. }
  226.  
  227.  
  228. /*
  229.  * Fallback for ctx->Driver.DrawBuffer()
  230.  */
  231. void
  232. _swrast_DrawBuffer( GLcontext *ctx, GLenum mode )
  233. {
  234.    _swrast_use_draw_buffer(ctx);
  235. }
  236.  
  237.  
  238. /*
  239.  * Setup things so that we read/write spans from the user-designated
  240.  * read buffer (set via glReadPixels).  We usually just have to call
  241.  * this for glReadPixels, glCopyPixels, etc.
  242.  */
  243. void
  244. _swrast_use_read_buffer( GLcontext *ctx )
  245. {
  246.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  247.  
  248.    /* Do this so the software-emulated alpha plane span functions work! */
  249.    swrast->CurrentBuffer = ctx->Pixel._ReadSrcMask;
  250.    /* Tell the device driver where to read/write spans */
  251.    (*swrast->Driver.SetBuffer)( ctx, ctx->ReadBuffer, swrast->CurrentBuffer );
  252. }
  253.  
  254.  
  255. /*
  256.  * Setup things so that we read/write spans from the default draw buffer.
  257.  * This is the usual mode that Mesa's software rasterizer operates in.
  258.  */
  259. void
  260. _swrast_use_draw_buffer( GLcontext *ctx )
  261. {
  262.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  263.  
  264.    /* The user can specify rendering to zero, one, two, or four color
  265.     * buffers simultaneously with glDrawBuffer()!
  266.     * We don't expect the span/point/line/triangle functions to deal with
  267.     * that mess so we'll iterate over the multiple buffers as needed.
  268.     * But usually we only render to one color buffer at a time.
  269.     * We set ctx->Color._DriverDrawBuffer to that buffer and tell the
  270.     * device driver to use that buffer.
  271.     * Look in s_span.c's multi_write_rgba_span() function to see how
  272.     * we loop over multiple color buffers when needed.
  273.     */
  274.  
  275.    if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
  276.       swrast->CurrentBuffer = FRONT_LEFT_BIT;
  277.    else if (ctx->Color._DrawDestMask & BACK_LEFT_BIT)
  278.       swrast->CurrentBuffer = BACK_LEFT_BIT;
  279.    else if (ctx->Color._DrawDestMask & FRONT_RIGHT_BIT)
  280.       swrast->CurrentBuffer = FRONT_RIGHT_BIT;
  281.    else if (ctx->Color._DrawDestMask & BACK_RIGHT_BIT)
  282.       swrast->CurrentBuffer = BACK_RIGHT_BIT;
  283.    else
  284.       /* glDrawBuffer(GL_NONE) */
  285.       swrast->CurrentBuffer = FRONT_LEFT_BIT; /* we always have this buffer */
  286.  
  287.    (*swrast->Driver.SetBuffer)( ctx, ctx->DrawBuffer, swrast->CurrentBuffer );
  288. }
  289.