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

  1. /* $Id: s_alphabuf.c,v 1.16 2002/11/26 02:58:43 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  5.0.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. /*
  29.  * Software alpha planes.  Many frame buffers don't have alpha bits so
  30.  * we simulate them in software.
  31.  */
  32.  
  33.  
  34. #include "glheader.h"
  35. #include "colormac.h"
  36. #include "context.h"
  37. #include "imports.h"
  38.  
  39. #include "s_context.h"
  40. #include "s_alphabuf.h"
  41.  
  42.  
  43. /*
  44.  * Allocate a new front and back alpha buffer.
  45.  */
  46. void
  47. _mesa_alloc_alpha_buffers( GLframebuffer *buffer )
  48. {
  49.    const GLint bytes = buffer->Width * buffer->Height * sizeof(GLchan);
  50.  
  51.    ASSERT(buffer->UseSoftwareAlphaBuffers);
  52.  
  53.    if (buffer->FrontLeftAlpha) {
  54.       MESA_PBUFFER_FREE( buffer->FrontLeftAlpha );
  55.    }
  56.    buffer->FrontLeftAlpha = MESA_PBUFFER_ALLOC( bytes );
  57.    if (!buffer->FrontLeftAlpha) {
  58.       /* out of memory */
  59.       _mesa_error( NULL, GL_OUT_OF_MEMORY,
  60.                    "Couldn't allocate front-left alpha buffer" );
  61.    }
  62.  
  63.    if (buffer->Visual.doubleBufferMode) {
  64.       if (buffer->BackLeftAlpha) {
  65.          MESA_PBUFFER_FREE( buffer->BackLeftAlpha );
  66.       }
  67.       buffer->BackLeftAlpha = MESA_PBUFFER_ALLOC( bytes );
  68.       if (!buffer->BackLeftAlpha) {
  69.          /* out of memory */
  70.          _mesa_error( NULL, GL_OUT_OF_MEMORY,
  71.                       "Couldn't allocate back-left alpha buffer" );
  72.       }
  73.    }
  74.  
  75.    if (buffer->Visual.stereoMode) {
  76.       if (buffer->FrontRightAlpha) {
  77.          MESA_PBUFFER_FREE( buffer->FrontRightAlpha );
  78.       }
  79.       buffer->FrontRightAlpha = MESA_PBUFFER_ALLOC( bytes );
  80.       if (!buffer->FrontRightAlpha) {
  81.          /* out of memory */
  82.          _mesa_error( NULL, GL_OUT_OF_MEMORY,
  83.                       "Couldn't allocate front-right alpha buffer" );
  84.       }
  85.  
  86.       if (buffer->Visual.doubleBufferMode) {
  87.          if (buffer->BackRightAlpha) {
  88.             MESA_PBUFFER_FREE( buffer->BackRightAlpha );
  89.          }
  90.          buffer->BackRightAlpha = MESA_PBUFFER_ALLOC( bytes );
  91.          if (!buffer->BackRightAlpha) {
  92.             /* out of memory */
  93.             _mesa_error( NULL, GL_OUT_OF_MEMORY,
  94.                          "Couldn't allocate back-right alpha buffer" );
  95.          }
  96.       }
  97.    }
  98. }
  99.  
  100.  
  101. /*
  102.  * Clear all the alpha buffers
  103.  */
  104. void
  105. _mesa_clear_alpha_buffers( GLcontext *ctx )
  106. {
  107.    GLchan aclear;
  108.    GLuint bufferBit;
  109.  
  110.    CLAMPED_FLOAT_TO_CHAN(aclear, ctx->Color.ClearColor[3]);
  111.  
  112.    ASSERT(ctx->DrawBuffer->UseSoftwareAlphaBuffers);
  113.    ASSERT(ctx->Color.ColorMask[ACOMP]);
  114.  
  115.    /* loop over four possible alpha buffers */
  116.    for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
  117.       if (bufferBit & ctx->Color._DrawDestMask) {
  118.          GLchan *buffer;
  119.          if (bufferBit == FRONT_LEFT_BIT) {
  120.             buffer = (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
  121.          }
  122.          else if (bufferBit == FRONT_RIGHT_BIT) {
  123.             buffer = (GLchan *) ctx->DrawBuffer->FrontRightAlpha;
  124.          }
  125.          else if (bufferBit == BACK_LEFT_BIT) {
  126.             buffer = (GLchan *) ctx->DrawBuffer->BackLeftAlpha;
  127.          }
  128.          else {
  129.             buffer = (GLchan *) ctx->DrawBuffer->BackRightAlpha;
  130.          }
  131.  
  132.          if (ctx->Scissor.Enabled) {
  133.             /* clear scissor region */
  134.             GLint j;
  135.             GLint rowLen = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
  136.             GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
  137.             GLint width = ctx->DrawBuffer->Width;
  138.             GLchan *aptr = buffer
  139.                           + ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width
  140.                           + ctx->DrawBuffer->_Xmin;
  141.             for (j = 0; j < rows; j++) {
  142. #if CHAN_BITS == 8
  143.                MEMSET( aptr, aclear, rowLen );
  144. #elif CHAN_BITS == 16
  145.                MEMSET16( aptr, aclear, rowLen );
  146. #else
  147.                GLint i;
  148.                for (i = 0; i < rowLen; i++) {
  149.                   aptr[i] = aclear;
  150.                }
  151. #endif
  152.                aptr += width;
  153.             }
  154.          }
  155.          else {
  156.             /* clear whole buffer */
  157.             GLuint pixels = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
  158. #if CHAN_BITS == 8
  159.             MEMSET(buffer, aclear, pixels);
  160. #elif CHAN_BITS == 16
  161.             MEMSET16(buffer, aclear, pixels);
  162. #else
  163.             GLuint i;
  164.             for (i = 0; i < pixels; i++) {
  165.                buffer[i] = aclear;
  166.             }
  167. #endif
  168.          }
  169.       }
  170.    }
  171. }
  172.  
  173.  
  174.  
  175. static INLINE
  176. GLchan *get_alpha_buffer( GLcontext *ctx )
  177. {
  178.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  179.  
  180.    switch (swrast->CurrentBuffer) {
  181.    case FRONT_LEFT_BIT:
  182.       return (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
  183.       break;
  184.    case BACK_LEFT_BIT:
  185.       return (GLchan *) ctx->DrawBuffer->BackLeftAlpha;
  186.       break;
  187.    case FRONT_RIGHT_BIT:
  188.       return (GLchan *) ctx->DrawBuffer->FrontRightAlpha;
  189.       break;
  190.    case BACK_RIGHT_BIT:
  191.       return (GLchan *) ctx->DrawBuffer->BackRightAlpha;
  192.       break;
  193.    default:
  194.       _mesa_problem(ctx, "Bad CurrentBuffer in get_alpha_buffer()");
  195.       return (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
  196.    }
  197. }
  198.  
  199.  
  200. void
  201. _mesa_write_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
  202.                         CONST GLchan rgba[][4], const GLubyte mask[] )
  203. {
  204.    GLchan *buffer, *aptr;
  205.    GLuint i;
  206.  
  207.    buffer = get_alpha_buffer(ctx);
  208.    aptr = buffer + y * ctx->DrawBuffer->Width + x;
  209.  
  210.    if (mask) {
  211.       for (i=0;i<n;i++) {
  212.          if (mask[i]) {
  213.             *aptr = rgba[i][ACOMP];
  214.          }
  215.          aptr++;
  216.       }
  217.    }
  218.    else {
  219.       for (i=0;i<n;i++) {
  220.          *aptr++ = rgba[i][ACOMP];
  221.       }
  222.    }
  223. }
  224.  
  225.  
  226. void
  227. _mesa_write_mono_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
  228.                              GLchan alpha, const GLubyte mask[] )
  229. {
  230.    GLchan *buffer, *aptr;
  231.    GLuint i;
  232.  
  233.    buffer = get_alpha_buffer(ctx);
  234.    aptr = buffer + y * ctx->DrawBuffer->Width + x;
  235.  
  236.    if (mask) {
  237.       for (i=0;i<n;i++) {
  238.          if (mask[i]) {
  239.             *aptr = alpha;
  240.          }
  241.          aptr++;
  242.       }
  243.    }
  244.    else {
  245.       for (i=0;i<n;i++) {
  246.          *aptr++ = alpha;
  247.       }
  248.    }
  249. }
  250.  
  251.  
  252. void
  253. _mesa_write_alpha_pixels( GLcontext *ctx,
  254.                           GLuint n, const GLint x[], const GLint y[],
  255.                           CONST GLchan rgba[][4], const GLubyte mask[] )
  256. {
  257.    GLchan *buffer;
  258.    GLuint i;
  259.  
  260.    buffer = get_alpha_buffer(ctx);
  261.  
  262.    if (mask) {
  263.       for (i=0;i<n;i++) {
  264.          if (mask[i]) {
  265.             GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
  266.             *aptr = rgba[i][ACOMP];
  267.          }
  268.       }
  269.    }
  270.    else {
  271.       for (i=0;i<n;i++) {
  272.          GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
  273.          *aptr = rgba[i][ACOMP];
  274.       }
  275.    }
  276. }
  277.  
  278.  
  279. void
  280. _mesa_write_mono_alpha_pixels( GLcontext *ctx,
  281.                                GLuint n, const GLint x[], const GLint y[],
  282.                                GLchan alpha, const GLubyte mask[] )
  283. {
  284.    GLchan *buffer;
  285.    GLuint i;
  286.  
  287.    buffer = get_alpha_buffer(ctx);
  288.  
  289.    if (mask) {
  290.       for (i=0;i<n;i++) {
  291.          if (mask[i]) {
  292.             GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
  293.             *aptr = alpha;
  294.          }
  295.       }
  296.    }
  297.    else {
  298.       for (i=0;i<n;i++) {
  299.          GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
  300.          *aptr = alpha;
  301.       }
  302.    }
  303. }
  304.  
  305.  
  306.  
  307. void
  308. _mesa_read_alpha_span( GLcontext *ctx,
  309.                        GLuint n, GLint x, GLint y, GLchan rgba[][4] )
  310. {
  311.    const GLchan *buffer, *aptr;
  312.    GLuint i;
  313.  
  314.    buffer = get_alpha_buffer(ctx);
  315.    aptr = buffer + y * ctx->DrawBuffer->Width + x;
  316.  
  317.    for (i = 0; i < n; i++)
  318.       rgba[i][ACOMP] = *aptr++;
  319. }
  320.  
  321.  
  322. void
  323. _mesa_read_alpha_pixels( GLcontext *ctx,
  324.                          GLuint n, const GLint x[], const GLint y[],
  325.                          GLchan rgba[][4], const GLubyte mask[] )
  326. {
  327.    const GLchan *buffer;
  328.    GLuint i;
  329.  
  330.    buffer = get_alpha_buffer(ctx);
  331.  
  332.    for (i = 0; i < n; i++) {
  333.       if (mask[i]) {
  334.          const GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
  335.          rgba[i][ACOMP] = *aptr;
  336.       }
  337.    }
  338. }
  339.